Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
syaifulnizamyahya
@syaifulnizamyahya
@onqtam Please have a look if you have time. Thanks.
Viktor Kirilov
@onqtam
@syaifulnizamyahya I call a test runner is not where you call doctest::Context().run() but where you have defined DOCTEST_CONFIG_IMPLEMENT - that basically conditionally compiles 1/2 of doctest - the test runner. doctest::Context() is calling into the test runner
see the doctest dll example again - DOCTEST_CONFIG_IMPLEMENT is defined in a single place
in your case there are 2 such cases
test runner == the implementation of the framework
when you include doctest.h you get the interface
when you define DOCTEST_CONFIG_IMPLEMENT and then include doctest.h you get the interface + the implementation
think of the doctest header as 2 files attached together - a header file (the interface) and a .cpp file (the implementation - the test runner)
when you #define DOCTEST_CONFIG_IMPLEMENT you pull the contents of that fictional .cpp along
I'm sorry but I'm not going to be able to look at your example in the near future - I'm knee-deep in work - I haven't had a free weekend in the past couple of months
hopefully my comments are helpful - if you're still not able to get it to work - it would be great if someone else helps. Otherwise I'll eventually get to helping with this, but I'm confident that the doctest dll example in the original repository should be enough to get the full picture
about from_dll - see the comment here:
Viktor Kirilov
@onqtam
the "dll" target in that CMake project only has a single test case. The executable links to it, but since it doesn't need anything from there (and doesn't know there is a self-registering test), and the dll doesn't dllexport anything - no .lib file will be created for it - or something like that - I've already forgotten
but in your case you have dlls with tests, and production code which you test. I guess you are already exporting some of that production code and using it from the main executable - you should already have a .lib file for your dlls
so you can just ignore the from_dll stuff from doctest's examples
syaifulnizamyahya
@syaifulnizamyahya
I have successfully created a simple project with multiple dlls using doctest. You can find it here if you have time. https://github.com/syaifulnizamyahya/doctest_multiple_dlls

The simple project have 2 dlls, dllA and dllB. I have a testrunner, which calls DOCTEST_CONFIG_IMPLEMENT. I have a testexecutable which calls doctest:Contest(). Each dlls calls DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL.

My question is, is this the best way to do it? Are there any other alternatives?

Viktor Kirilov
@onqtam

@syaifulnizamyahya This is the best way if you want to have a single test runner (a single place where DOCTEST_CONFIG_IMPLEMENT is defined) - that way all the tests from all .dlls will be registered in a single place. This way you could choose which dlls to load from the executable and thus choose which tests to have registered. You could also use the command line filtering functionality to choose tests from specific .cpp files or based on a pattern or test suite - you could use test suites for the different dlls.

A potential alternative might be to have a test runner in each dll but then you would need to have DOCTEST_CONFIG_IMPLEMENT in each dll and also create and use a doctest::Context object in the dllMain of each dll.

syaifulnizamyahya
@syaifulnizamyahya
Thanks @onqtam . Things working out pretty well for me here. doctest is great. :)
syaifulnizamyahya
@syaifulnizamyahya
if I use DOCTEST_INFO, i get this error message. Error C2201 'const doctest::detail::ContextScope<<lambda_6a0134cc54c94a1b514892dbb179d44f> >::vftable'': must have external linkage in order to be exported/imported. ` Not sure why that happens.
In the cmake target link libraries
target_link_libraries(${LIBRARY_NAME}
    doctest
)
in cpp
#define DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
#define DOCTEST_CONFIG_IMPLEMENT
#define DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
#include "doctest.h"

DOCTEST_TEST_CASE("testrunner") {
    DOCTEST_INFO("From testrunner\n");
}
syaifulnizamyahya
@syaifulnizamyahya
it doesnt happen if I use DOCTEST_MESSAGE. Whats the difference between info and message?
syaifulnizamyahya
@syaifulnizamyahya
I have another issue. Not sure if its related to doctest. In my dll, if i update/change the tests, the changes are not being picked up. i still the the old test results. How does doctest works in this regard? are there cache files i need to clear?
Viktor Kirilov
@onqtam
I'll respond later about the INFO/MESSAGE problem, but about the changes not being picked up - are you sure the dlls are getting properly rebuilt by the build system? If we ignore the tests - are your changes picked up in the actual program? There are no caches in doctest...
syaifulnizamyahya
@syaifulnizamyahya
There are no caches in doctest... Ok. I guess the problem is on my side. Thanks for the confirmation.
Viktor Kirilov
@onqtam
@syaifulnizamyahya thanks for catching that bug - that INFO cannot be used from within a dll! I logged it here: onqtam/doctest#306
Viktor Kirilov
@onqtam
and it should be fixed in the dev branch - I'll release an official version (into the master branch) when a few more things accumulate :)
syaifulnizamyahya
@syaifulnizamyahya
:) Thanks.
syaifulnizamyahya
@syaifulnizamyahya
When my tests fails, i get a breakpoint on where the test fails. Is it possible to disable this? i might have multiple fail tests during development and only interested in the failed tests when im ready(done development). I notice there are some defines that might be related to this. but im not sure which one. DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS or DOCTEST_CONFIG_NO_EXCEPTIONS or DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS or DOCTEST_CONFIG_SUPER_FAST_ASSERTS? What is the workflow that you guys use?
Viktor Kirilov
@onqtam
@syaifulnizamyahya what you need is --no-breaks from the command line options: https://github.com/onqtam/doctest/blob/master/doc/markdown/commandline.md
You could also set it by default in your main() function with the ability to override it through the command line: https://github.com/onqtam/doctest/blob/master/doc/markdown/main.md (the option is used in the example as well - but as an override - move that above the call to applyCommandLine() and it will be a default instead of an override)
syaifulnizamyahya
@syaifulnizamyahya
got it. thanks
syaifulnizamyahya
@syaifulnizamyahya
@onqtam Hi Viktor. Would it be possible to separate logging macro and test macro? I want to use test shorthand macro but doctest logging macro conflicted with my logging setup. Specifically, INFO shorthand macro from doctest conflicted with my loggin INFO macro. while i can disable it myself in the doctest header, i wonder if you can make it officially separated?
Viktor Kirilov
@onqtam
Do you mean that your source code also has a #define INFO ... which conflicts with the one from doctest? In that case you could use DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES and perhaps a proxy header for including doctest like this: https://github.com/onqtam/doctest/blob/master/examples/all_features/doctest_proxy.h
syaifulnizamyahya
@syaifulnizamyahya
@onqtam Hi Viktor. If I add comma to test case name, the tests are being ignored. Eg. DOCTEST_TEST_CASE("WorkspaceService - 1st") is fine, but if its DOCTEST_TEST_CASE("WorkspaceService , 1st")its being ignored. Not sure why.
Viktor Kirilov
@onqtam
@syaifulnizamyahya I just tried it and it doesn't matter if there is a comma in the name or not. But I tried it without any filters on the command line - are you using such? Perhaps this is a related issue: onqtam/doctest#297
syaifulnizamyahya
@syaifulnizamyahya
Yup. I believe its the same issue. Thanks.
syaifulnizamyahya
@syaifulnizamyahya
@onqtam Just curious. What mocking library have you use? What mocking library you are currently using? Why?
syaifulnizamyahya
@syaifulnizamyahya
I already looked at that links. I was expecting a more personal preference/experience actually. Anyway, thanks.
Viktor Kirilov
@onqtam
Well actually I've never used mocking, and even in my current company we use google test because it was already integrated when I joined and there is not big need to switch... And for google test if we need mocks we would use google mock.
Tim
@Gohlisch

Hey, I just started C++ programming and found DocTest. I was just wondering if my way of disabling tests is the correct one.

I followed the main.md and had no problems. When I tried #define DOCTEST_CONFIG_DISABLE the compiler couldn't find symbols like doctest::Context context etc (which wasn't surprising).

Is the correct way to put everything test related in a if(!DOCTEST_CONFIG_DISABLE) {...DocTest stuff here...} statement, so that the compiler ignores it?

Viktor Kirilov
@onqtam
@Gohlisch that's strange - can you paste the exact error messages you are getting? Compiler or linker errors? It should be as simple as defining DOCTEST_CONFIG_DISABLE for the entire project and it should continue to compile - including a custom main function which uses doctest::Context...
that's where the implementation of the Context class is defined when DOCTEST_CONFIG_DISABLE is defined - the methods are empty stubs precisely so that users don't need to do anything extra
Tim
@Gohlisch

math.cpp:

#define DOCTEST_CONFIG_DISABLE
#include "doctest.h" 
#include <iostream>

int add(int a, int b) {
    return a+b;
}

TEST_CASE("testing add func") {
    CHECK(add(0, 0) == 0);
    CHECK(add(1, 0) == 1);
    CHECK(add(1, 1) == 2);
    CHECK(add(0, -1) == -1);
    CHECK(add(-1, -1) == -2);
}

int main(int argc, char** argv) {
    doctest::Context context;
    context.setOption("abort-after", 5); 
    context.applyCommandLine(argc, argv);
    context.setOption("no-breaks", true);
    int res =  context.run();
    if(context.shouldExit())    
        return res;             
    std::cout << add(1, 2);
    return res;
}

using: g++ math.cpp -o math -std=c++2a
leads to
Undefined symbols for architecture x86_64: "doctest::Context::shouldExit()", referenced from: _main in math-161803.o "doctest::Context::applyCommandLine(int, char const* const*)", referenced from: _main in math-161803.o "doctest::Context::run()", referenced from: _main in math-161803.o "doctest::Context::setOption(char const*, int)", referenced from: _main in math-161803.o "doctest::Context::Context(int, char const* const*)", referenced from: _main in math-161803.o "doctest::Context::~Context()", referenced from: _main in math-161803.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

If I use #define DOCTEST_CONFIG_IMPLEMENT everything seems to work as intended.

Viktor Kirilov
@onqtam
@Gohlisch oh - you shouldn't swap out one for the other - #define DOCTEST_CONFIG_IMPLEMENT must always be present in at least one .cpp file, and whether you have defined DOCTEST_CONFIG_DISABLE globally is a completely separate matter. Those stubs I pointed to require DOCTEST_CONFIG_IMPLEMENT.
so to disable all tests you should define DOCTEST_CONFIG_DISABLE in addition to DOCTEST_CONFIG_IMPLEMENT
Tim
@Gohlisch
Ah, all right. I can't believe I haven't tried that. Thanks for your quick help.