Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use doctest in dll only(without main.cpp and .exe) #299

Closed
syaifulnizamyahya opened this issue Oct 10, 2019 · 6 comments
Closed

How to use doctest in dll only(without main.cpp and .exe) #299

syaifulnizamyahya opened this issue Oct 10, 2019 · 6 comments

Comments

@syaifulnizamyahya
Copy link

syaifulnizamyahya commented Oct 10, 2019

Description

I created a simple dll project from visual studio 2019(using the wizard) and then I add doctest.h and a test in the dllmain.cpp.

The dllmain.cpp looks like this.

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#define DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"

DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#include <cstdio>
DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

TEST_CASE("test dll") {
    printf("I am a test from the dll!\n");
}

DOCTEST_SYMBOL_EXPORT void from_dll();   // to silence "-Wmissing-declarations" with GCC
DOCTEST_SYMBOL_EXPORT void from_dll() {} // force the creation of a .lib file with MSVC

While the code compiles, i cant

  1. run the test
  2. use the resharper to run the test

Probably because without main, there is no test runner.

Is it possible to create test inside a dll and test it without main?

@onqtam
Copy link
Member

onqtam commented Oct 10, 2019

DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN means that doctest will define a main(int, char**) function - I guess it compiles successfully but your dllmain function takes precedence. In order to just implement the test framework you should use DOCTEST_CONFIG_IMPLEMENT without the _WITH_MAIN part at the end.

since you'll be defining the entry point (in this case DllMain) I guess you should look at providing your own main - you could just create a doctest::Context object and call run() on it to have the tests executed whenever the .dll is loaded and DllMain gets called.

On the resharper stuff - I suggest you follow their instructions on how to integrate doctest and discover tests and whatnot - I'm still not familiar with their plugin for Visual Studio (but am really happy that they worked on that!).

Also you'll be needing DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL only if you'll be making multiple .dlls and want all the tests to be registered in a single test registry/runner, but if all you have is a single .dll then you don't need that.

And another note: you could remove the from_dll and DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN / END stuff - those are meant just for compiling the doctest examples with the highest possible warning levels - something which is really unnecessary.

Let me know if this helps :)

@syaifulnizamyahya
Copy link
Author

syaifulnizamyahya commented Oct 11, 2019

Updated code.

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#define DOCTEST_CONFIG_IMPLEMENT
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"

#include <cstdio>

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }

    doctest::Context context{};
    const auto doctestResult = context.run();

    if (context.shouldExit())
        return doctestResult;

    return TRUE;
}

TEST_CASE("test dll") {
    printf("I am a test from the dll!\n");
}

DOCTEST_SYMBOL_EXPORT void from_dll();   // to silence "-Wmissing-declarations" with GCC
DOCTEST_SYMBOL_EXPORT void from_dll() {} // force the creation of a .lib file with MSVC

Is it possible to run this test without exe? If so how? I cant get it to run since its only dll. Using resharper also doesnt help(if it need to re-configure, i dont know how). Probably impossible since it somehow need a test runner. Not sure.

Thanks. for replying.

@syaifulnizamyahya
Copy link
Author

My situation is, I have multiple dlls. Around 20 i guess. Right now I create doctest context in my main which will call all the dlls and run the test.

Ideally, i would like the ability to execute the test on the dll only. Meaning that only compile specific dll, and run the desired test inside the dll. its faster since it only compile the specific dll(and its dependencies). I assume that in each dll, we could supply DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN so that a main will be created which will call the dll behind the scene. Maybe thats not the case.

Anyway, what are your thoughts.

@onqtam
Copy link
Member

onqtam commented Oct 11, 2019

In order to execute tests in a .dll you will need an .exe to load it - this is true even without tests - if you need the code in a .dll to be used someone needs to load/use it. If you want to compile only a specific .dll and execute the tests in it, you'll need a separate project which compiles to an .exe and links against the .dll (or loads it at runtime with LoadLibrary()).

In the code which you provided you're writing your own main() function (DllMain in this case) - that means you only need DOCTEST_CONFIG_IMPLEMENT and not DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN - see the difference - it just adds a main() in addition to what DOCTEST_CONFIG_IMPLEMENT is doing, and that's an entry point for an executable - not a .dll.

@onqtam
Copy link
Member

onqtam commented Oct 16, 2019

after our discussion in the gitter channel I suppose we could close this issue? :)

@wxinix-2022
Copy link

I have a Windows GUI host, and a doctest DLL with all the test cases. From inside the DLL, how can I specify to output the test messages to a text file? Also is there a way to attach to a console and see the messages?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants