nit: Added link to `CONTRIBUTING.md` from the README
[nit.git] / share / man / nitunit.md
index 4f45562..e80e80e 100644 (file)
@@ -1,5 +1,3 @@
-% NITUNIT(1)
-
 # NAME
 
 nitunit - executes the unit tests from Nit source files.
@@ -12,14 +10,16 @@ nitunit [*options*] FILE...
 
 Unit testing in Nit can be achieved in two ways:
 
-* using `DocUnits` in code comments
+* using `DocUnits` in code comments or in markdown files
 * using `TestSuites` with test unit files
 
-`DocUnits` are executable pieces of code found in the documentation of modules,
+`DocUnits` are executable pieces of code found in the documentation of groups, modules,
 classes and properties.
 They are used for documentation purpose, they should be kept simple and illustrative.
 More advanced unit testing can be done using TestSuites.
 
+`DocUnits` can also be used in any markdown files.
+
 `TestSuites` are test files coupled to a tested module.
 They contain a list of test methods called TestCase.
 
@@ -30,24 +30,28 @@ The execution can be verified using `assert`.
 
 Example with a class:
 
-    module foo
-    #    var foo = new Foo
-    #    assert foo.bar == 10
-    class Foo
-        var bar = 10
-    end
+~~~
+module foo
+#    var foo = new Foo
+#    assert foo.bar == 10
+class Foo
+    var bar = 10
+end
+~~~
 
 Everything used in the test must be declared.
 To test a method you have to instantiate its class:
 
-    module foo
+~~~
+module foo
+#    var foo = new Foo
+#    assert foo.bar == 10
+class Foo
     #    var foo = new Foo
-    #    assert foo.bar == 10
-    class Foo
-        #    var foo = new Foo
-        #    assert foo.baz(1, 2) == 3
-        fun baz(a, b: Int) do return a + b
-    end
+    #    assert foo.baz(1, 2) == 3
+    fun baz(a, b: Int) do return a + b
+end
+~~~
 
 In a single piece of documentation, each docunit is considered a part of a single module, thus regrouped when
 tested.
@@ -106,6 +110,23 @@ The `nitunit` command is used to test Nit files:
 
     $ nitunit foo.nit
 
+Groups (directories) can be given to test the documentation of the group and of all its Nit files:
+
+    $ nitunit lib/foo
+
+Finally, standard markdown documents can be checked with:
+
+    $ nitunit foo.md
+
+When testing, the environment variable `NIT_TESTING` is set to `true`.
+This flag can be used by libraries and program to prevent (or limit) the execution of dangerous pieces of code.
+
+~~~~~
+# NIT_TESTING is automatically set.
+#
+#     assert "NIT_TESTING".environ == "true"
+~~~~
+
 ## Working with `TestSuites`
 
 TestSuites are Nit files that define a set of TestCases for a particular module.
@@ -115,16 +136,18 @@ So for the module `foo.nit` the test suite will be called `test_foo.nit`.
 
 The structure of a test suite is the following:
 
-    # test suite for module `foo`
-    module test_foo
-    import foo # can be intrude to test private things
-    class TestFoo
-        # test case for `foo::Foo::baz`
-        fun test_baz do
-            var subject = new Foo
-            assert subject.baz(1, 2) == 3
-        end
+~~~~
+# test suite for module `foo`
+module test_foo
+import foo # can be intrude to test private things
+class TestFoo
+    # test case for `foo::Foo::baz`
+    fun test_baz do
+        var subject = new Foo
+        assert subject.baz(1, 2) == 3
     end
+end
+~~~~
 
 Test suite can be executed using the same `nitunit` command:
 
@@ -133,112 +156,184 @@ Test suite can be executed using the same `nitunit` command:
 `nitunit` will execute a test for each method named `test_*` in a class named `Test*`
 so multiple tests can be executed for a single method:
 
-    class TestFoo
-        fun test_baz_1 do
-            var subject = new Foo
-            assert subject.baz(1, 2) == 3
-        end
-        fun test_baz_2 do
-            var subject = new Foo
-            assert subject.baz(1, -2) == -1
-        end
+~~~~
+class TestFoo
+    fun test_baz_1 do
+        var subject = new Foo
+        assert subject.baz(1, 2) == 3
     end
+    fun test_baz_2 do
+        var subject = new Foo
+        assert subject.baz(1, -2) == -1
+    end
+end
+~~~~
+
+## Black Box Testing
+
+Sometimes, it is easier to validate a `TestCase` by comparing its output with a text file containing the expected result.
+
+For each TestCase `test_bar` of a TestSuite `test_mod.nit`, if the corresponding file `test_mod.sav/test_bar.res` exists, then the output of the test is compared with the file.
+
+The `diff(1)` command is used to perform the comparison.
+The test is failed if non-zero is returned by `diff`.
+
+~~~
+module test_mod is test_suite
+class TestFoo
+       fun test_bar do
+               print "Hello!"
+       end
+end
+~~~
+
+Where `test_mod.sav/test_bar.res` contains
+
+~~~raw
+Hello!
+~~~
+
+If no corresponding `.res` file exists, then the output of the TestCase is ignored.
+
+## Configuring TestSuites
 
 `TestSuites` also provide methods to configure the test run:
 
 `before_test` and `after_test`: methods called before/after each test case.
 They can be used to factorize repetitive tasks:
 
-    class TestFoo
-        var subject: Foo
-        # Mandatory empty init
-        init do end
-        # Method executed before each test
-        fun before_test do
-            subject = new Foo
-        end
-        fun test_baz_1 do
-            assert subject.baz(1, 2) == 3
-        end
-        fun test_baz_2 do
-            assert subject.baz(1, -2) == -1
-        end
+~~~~
+class TestFoo
+    var subject: Foo
+    # Mandatory empty init
+    init do end
+    # Method executed before each test
+    fun before_test do
+        subject = new Foo
+    end
+    fun test_baz_1 do
+        assert subject.baz(1, 2) == 3
     end
+    fun test_baz_2 do
+        assert subject.baz(1, -2) == -1
+    end
+end
+~~~~
 
 When using custom test attributes, an empty `init` must be declared to allow automatic test running.
 
 `before_module` and `after_module`: methods called before/after each test suite.
 They have to be declared at top level:
 
-    module test_bdd_connector
-    import bdd_connector
-    # Testing the bdd_connector
-    class TestConnector
-        # test cases using a server
-    end
-    # Method executed before testing the module
-    fun before_module do
-        # start server before all test cases
-    end
-    # Method executed after testing the module
-    fun after_module do
-        # stop server after all test cases
-    end
+~~~~
+module test_bdd_connector
+import bdd_connector
+# Testing the bdd_connector
+class TestConnector
+    # test cases using a server
+end
+# Method executed before testing the module
+fun before_module do
+    # start server before all test cases
+end
+# Method executed after testing the module
+fun after_module do
+    # stop server after all test cases
+end
+~~~~
 
 ## Generating test suites
 
- Write test suites for big modules can be a repetitive and boring task...
- To make it easier, `nitunit` can generate test skeletons for Nit modules:
+Write test suites for big modules can be a repetitive and boring task...
+To make it easier, `nitunit` can generate test skeletons for Nit modules:
 
     $ nitunit --gen-suite foo.nit
 
- This will generate the test suite `test_foo` containing test case stubs for all public
- methods found in `foo.nit`.
+This will generate the test suite `test_foo` containing test case stubs for all public
+methods found in `foo.nit`.
 
 
 # OPTIONS
 
-`--full`
-:   Process also imported modules.
+### `--full`
+Process also imported modules.
+
+By default, only the modules indicated on the command line are tested.
 
-    By default, only the modules indicated on the command line are tested.
+With the `--full` option, all imported modules (even those in standard) are also precessed.
 
-    With the `--full` option, all imported modules (even those in standard) are also precessed.
+### `-o`, `--output`
+Output name (default is 'nitunit.xml').
 
-`-o`, `--output`
-:   Output name (default is 'nitunit.xml')
+`nitunit` produces a XML file compatible with JUnit.
 
-    `nitunit` produces a XML file comatible with JUnit.
+### `--dir`
+Working directory (default is '.nitunit').
 
-`--dir`
-:   Working directory (default is '.nitunit')
+In order to execute the tests, nit files are generated then compiled and executed in the giver working directory.
 
-    In order to execute the tests, nit files are generated then compiled and executed in the giver working directory.
+### `--nitc`
+nitc compiler to use.
 
-`--no-act`
-:   Does not compile and run tests.
+By default, nitunit tries to locate the `nitc` program with the environment variable `NITC` or heuristics.
+The option is used to indicate a specific nitc binary.
 
-`-p`, `--pattern`
-:   Only run test case with name that match pattern. Examples: `TestFoo`, `TestFoo*`, `TestFoo::test_foo`, `TestFoo::test_foo*`, `test_foo`, `test_foo*`
+### `--no-act`
+Does not compile and run tests.
 
-`-t`, `--target-file`
-:   Specify test suite location.
+### `-p`, `--pattern`
+Only run test case with name that match pattern.
+
+Examples: `TestFoo`, `TestFoo*`, `TestFoo::test_foo`, `TestFoo::test_foo*`, `test_foo`, `test_foo*`
+
+### `-t`, `--target-file`
+Specify test suite location.
 
 ## SUITE GENERATION
 
-`--gen-suite`
-:   Generate test suite skeleton for a module
+### `--gen-suite`
+Generate test suite skeleton for a module.
+
+### `-f`, `--force`
+Force test generation even if file exists.
+
+Any existing test suite will be overwritten.
+
+### `--private`
+Also generate test case for private methods.
+
+### `--only-show`
+Only display the skeleton, do not write any file.
+
+
+# ENVIRONMENT VARIABLES
+
+### `NITC`
+
+Indicate the specific Nit compiler executable to use. See `--nitc`.
+
+### `NIT_TESTING`
+
+The environment variable `NIT_TESTING` is set to `true` during the execution of program tests.
+Some libraries of programs can use it to produce specific reproducible results; or just to exit their executions.
+
+Unit-tests may unset this environment variable to retrieve the original behavior of such piece of software.
+
+### `SRAND`
+
+In order to maximize reproducibility, `SRAND` is set to 0.
+This make the pseudo-random generator no random at all.
+See `Sys::srand` for details.
+
+To retrieve the randomness, unit-tests may unset this environment variable then call `srand`.
 
-`-f`, `--force`
-:   Force test generation even if file exists.
+### `NIT_TESTING_ID`
 
-    Any existing test suite will be overwritten.
+Parallel executions can cause some race collisions on named resources (e.g. DB table names).
+To solve this issue, `NIT_TESTING_ID` is initialized with a distinct integer identifier that can be used to give unique names to resources.
 
-`--private`
-:   Also generate test case for private methods.
+Note: `rand` is not a recommended way to get a distinct identifier because its randomness is disabled by default. See `SRAND`.
 
-`--only-show`
-:   Only display the skeleton, do not write any file.
 
 # SEE ALSO