Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

128 lines
4.4KB

  1. A *Hello, World* Test
  2. #####################
  3. So far, we have a simple library with a single function: ``get_greeting()``
  4. and an application that makes use of it. How can we test it?
  5. With ``dds``, similar to generating applications, creating a test requires
  6. adding a suffix to a source filename stem. Instead of ``.main``, simply
  7. add ``.test`` before the file extension.
  8. A New Test Executable
  9. *********************
  10. We'll create a test for our ``strings`` component, in a file named
  11. ``strings.test.cpp``. We'll use an ``assert`` to check our ``get_greeting()``
  12. function:
  13. .. code-block:: c++
  14. :caption: ``<root>/src/hello/strings.test.cpp``
  15. :linenos:
  16. #include <hello/strings.hpp>
  17. int main() {
  18. if (hello::get_greeting() != "Hello world!") {
  19. return 1;
  20. }
  21. }
  22. If you run ``dds build`` once again, ``dds`` will generate a test executable
  23. and run it immediately. If the test executable exits with a non-zero exit code,
  24. then it will consider the test to have failed, and ``dds`` itself will exit
  25. with a non-zero exit code.
  26. .. important::
  27. ``dds`` executes tests *in parallel* by default! If the tests need access
  28. to a shared resource, locking must be implemented manually, or the shared
  29. resource should be split.
  30. .. note::
  31. ``dds`` builds and executes tests for *every build* **by default**. The
  32. ``*.test.cpp`` tests are meant to be very fast *unit* tests, so consider
  33. their execution time carefully.
  34. If your code matches the examples so far, the above test will *fail*. Keen eyes
  35. will already know the problem, but wouldn't it be better if we had better test
  36. diagnostics?
  37. A ``Test-Driver``: Using *Catch2*
  38. *********************************
  39. ``dds`` ships with built-in support for the `Catch2`_ C and C++ testing
  40. framework, a popular
  41. .. _catch2: https://github.com/catchorg/Catch2
  42. To make use of Catch as our test driver, we simply declare this intent in the
  43. ``package.dds`` file at the package root:
  44. .. code-block:: yaml
  45. :caption: ``<root>/package.dds``
  46. :emphasize-lines: 5
  47. Name: hello-dds
  48. Version: 0.1.0
  49. Namespace: tutorial
  50. Test-Driver: Catch-Main
  51. If you now run ``dds build``, we will get a linker error for a multiply-defined
  52. ``main`` function. When setting the ``Test-Driver`` to ``Catch-Main``, ``dds``
  53. will compile an entrypoint separately from any particular test, and the tests
  54. will link against that entrypoint. This means we cannot provide our own
  55. ``main`` function, and should instead use Catch's ``TEST_CASE`` macro to
  56. declare our test cases.
  57. In addition to an entrypoint, ``dds`` provides a ``catch.hpp`` header that we
  58. may use in our tests, simply by ``#include``-ing the appropriate path. We'll
  59. modify our test to use the Catch test macros instead of our own logic. We'll
  60. leave the condition the same, though:
  61. .. code-block:: c++
  62. :caption: ``<root>/src/hello/strings.test.cpp``
  63. :linenos:
  64. :emphasize-lines: 3, 5-7
  65. #include <hello/strings.hpp>
  66. #include <catch2/catch.hpp>
  67. TEST_CASE("Check the greeting") {
  68. CHECK(hello::get_greeting() == "Hello world!");
  69. }
  70. Now running ``dds build`` will print more output that Catch has generated as
  71. part of test execution, and we can see the reason for the failing test::
  72. [16:41:45] [error] Test <root>/_build/test/hello/strings failed! Output:
  73. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  74. strings is a Catch v2.10.2 host application.
  75. Run with -? for options
  76. -------------------------------------------------------------------------------
  77. Check the greeting
  78. -------------------------------------------------------------------------------
  79. <root>/src/hello/strings.test.cpp:5
  80. ...............................................................................
  81. <root>/src/hello/strings.test.cpp:5: FAILED:
  82. CHECK( hello::get_greeting() == "Hello world!" )
  83. with expansion:
  84. "Hello, world!" == "Hello world!"
  85. ===============================================================================
  86. test cases: 1 | 1 failed
  87. assertions: 1 | 1 failed
  88. [dds - test output end]
  89. Now that we have the direct results of the offending expression, we can
  90. much more easily diagnose the nature of the test failure. In this case, the
  91. function returns a string containing a comma ``,`` while our expectation lacks
  92. one. If we fix either the ``get_greeting`` or the expected string, we will then
  93. see our tests pass successfully and ``dds`` will exit cleanly.