1---
2title: Automation of unit-tests of scientific tools using `tfel-check`
3author: Thomas Helfer, Stéphane Bernaud
4date: 21/11/2017
5lang: en-EN
6link-citations: true
7colorlinks: true
8figPrefixTemplate: "$$i$$"
9tabPrefixTemplate: "$$i$$"
10secPrefixTemplate: "$$i$$"
11eqnPrefixTemplate: "($$i$$)"
12---
13
14`tfel-check` is a tool designed to launch unit-tests and provide tools
15to test the outputs. `tfel-check` mostly targets scientific application
16which does not have in-house abilities to compare their results to
17reference results.
18
19# Overview
20
21## Basic usage
22
23The basic usage of `tfel-check` is simply to call `tfel-check` without
24options:
25
26~~~~{.bash}
27$ tfel-check
28~~~~
29
30`tfel-check` will then execute the tests and comparisons described in
31every file with the extension `.check` in the current directory and,
32recursively, in all the subdirectories. The syntax of of those files are
33described in Section @sec:tfel_check:input_files.
34
35One may also specify only a set of files to be considered, as follows:
36
37~~~~{.bash}
38$ tfel-check test1.check test2.check
39~~~~
40
41One may also specify a configuration file using the `--config` command
42line option, as follows:
43
44~~~~{.bash}
45$ tfel-check --config=test.config
46~~~~
47
48The configuration files are described in Section
49@sec:tfel_check:configuration_files.
50
51Substitution strings can be specified in configuration files or in the
52command line, as follows:
53
54~~~~{.bash}
55$ tfel-check --@python@=python3.5
56~~~~
57
58With this option, every occurrence of `@python@` will be replaced by
59`python3.5`.
60
61## A first example
62
63Let us consider this simple test file:
64
65~~~~{.cxx}
66@Requires {"tfel::madnex","mfront::python"};
67@Command "@python@ OverridableImplementation.py";
68@Command "mfront-query --author --material=A316LN --behaviour=Plasticity_SRMA2022 Plasticity.madnex"{
69  expected_output : "John Mac Enroe"
70};
71~~~~
72
73The first line, which begins with the `@Requires` keywords, provides a
74list of required components. In this case, the components `tfel::madnex`
75and `mfront::python` are required to execute the tests described in this
76file. The tests are skipped if those requirements are not met. The
77definition of components can be done in a configuration file, as
78detailed in Section @sec:tfel_check:configuration_files. The components
79defined by defaults by `tfel-check` is described in Section
80@sec:tfel_check:default_components.
81
82The second line specifies the first command to be run and begins with the
83`@Command` keyword. It is followed by the command to be launched. The
84`@python@` syntax designates that a substitution string must be provided
85to precise the `python` interpreter to be used.
86
87The third line specifies a second command which launches `mfront-query`
88and a first test which compares the command line output to an expected
89one.
90
91This file can can be launched as follows:
92
93~~~~{.bash}
94$ tfel-check --@python@=python3.5 madnex.check
95entering directory '/tmp/madnex'
96* beginning of test './madnex.check'
97** Exec-1 python3.5 MadnexTest.py                                      [SUCCESS]
98** Exec-2 python3.5 OverridableImplementation.py                       [SUCCESS]
99** Exec-3 mfront-query --author --material=A316LN --behaviour=Plast... [SUCCESS]
100* end of test './madnex.check'                                         [SUCCESS]
101======
102~~~~
103
104This command produces several files:
105
106- `tfel-check.log`: this file contains the ouptut of `tfel-check`. This
107  file is created in the directory where `tfel-check` has been invoked.
108- `madnex.checklog`: this file contains a summary of the execution of
109  the commands and test described in the `madnex.check` file. A similar
110  file is created for each file considered by `tfel-check`.
111- Three files `madnex-Exec-1.out`, `madnex-Exec-2.out` and
112  `madnex-Exec-3.out` associated to the three commands listed in the
113  `madnex.check` file. Those files contains the output of each commands
114  and the execution time of the command.
115- `TEST-madnex.xml` is an `XML` file conforming the `JUnit` standard
116  that summarises the results and which is suitable for the integration
117  of the test case in the [`jenkins` automation
118  server](https://www.jenkins.io/).
119
120If the requirements are not met, the executation and the tests are
121marked as skipped:
122
123~~~~{.bash}
124$ tfel-check
125entering directory '/tmp/madnex'
126* beginning of test './madnex.check'
127** Exec-1 @python@ MadnexTest.py                                       [SKIPPED]
128** Exec-2 @python@ OverridableImplementation.py                        [SKIPPED]
129** Exec-3 mfront-query --author --material=A316LN --behaviour=Plast... [SKIPPED]
130* end of test './madnex.check'                                         [SUCCESS]
131======
132~~~~
133
134If the execution of a command fails, this is reported as follows:
135
136~~~~{.bash}
137$ tfel-check --@python@=python2.7
138entering directory '/tmp/madnex'
139* beginning of test './madnex.check'
140** Exec-1 toto MadnexTest.py                                           [ FAILED]
141** Exec-2 toto OverridableImplementation.py                            [ FAILED]
142** Exec-3 mfront-query --author --material=A316LN --behaviour=Plast... [ FAILED]
143* end of test './madnex.check'                                         [ FAILED]
144======
145~~~~
146
147## A more complex example
148
149For this second example, let us consider a tensile test simulated using
150the `Cast3M` finite element solver. The test case uses an `MFront` file
151to define the behaviour and generates a text file called
152`ImplicitSimoMieheElastoPlasticityUniaxialTesting-castem.res` containing
153the evolution of the stress along the tensile axis as a function of
154time.
155
156The `ImplicitSimoMieheElastoPlasticity.check` file has the following
157content:
158
159~~~~{.cxx}
160@Requires {"Cast3M", "mfront::behaviour::castem_interface"};
161@Command "mfront --obuild --interface=castem ImplicitSimoMieheElastoPlasticity.mfront";
162@Command "@castem@ ImplicitSimoMieheElastoPlasticityUniaxialTesting.dgibi";
163
164@Precision 100; // criterion for the check, here a difference of 100Pa is allowed
165@Test "ImplicitSimoMieheElastoPlasticityUniaxialTesting-castem.res"
166      "ImplicitSimoMieheElastoPlasticityUniaxialTesting-castem.ref" 2;
167~~~~
168
169The first line specifies that the `Cast3M` component must be available
170and that the support of the `Cast3M` interface is available in `MFront`.
171The second line compiles the behaviour.
172
173The third one launches the `Cast3M` simulation. This line assumes that a
174substitution string for the `@castem@` pattern has been defined.
175
176The fifth line specify an absolute criterion to compare the current
177results to the reference ones. The last line defines the test to be
178performed: the values of the second column of the two specified files
179are compared using an absolute criteria.
180
181To trigger those tests, the following config file, called
182`castem.config` can be used:
183
184~~~~{.cxx}
185components : {"Cast3M"};
186substitutions : {"castem": "castem2019_PLEIADES"};
187~~~~
188
189The tests are run as follows:
190
191~~~~{.bash}
192$ tfel-check --config=castem.config
193entering directory '/tmp/tfel-check'
194* beginning of test './ImplicitSimoMieheElastoPlasticity.check'
195** Exec-1 mfront --obuild --interface=castem ImplicitSimoMieheElast... [SUCCESS]
196** Exec-2 castem2019_PLEIADES ImplicitSimoMieheElastoPlasticityUnia... [SUCCESS]
197** Compare-1 'ImplicitSimoMieheElastoPlasticityUniaxialTesting-cast... [SUCCESS]
198* end of test './ImplicitSimoMieheElastoPlasticity.check'              [SUCCESS]
199~~~~
200
201# Description of the input files{#sec:tfel_check:input_files}
202
203## List of available keywords
204
205### The `@Requires` keyword
206
207The `@Requires` keyword specifies the components that are required to
208run the tests described in the considered input file.
209
210### The `@Environment` keyword
211
212The `@Environment` keyword specifies a set of environment variables that
213will be defined accessible to the commands.
214
215### The `@Command` keyword
216
217The `@Command` keyword specifies a command to be launched.
218
219This keyword has the following options:
220
221- `expected_output`: a string specifying the expected output. If the
222  actual output differs from the expected one, the tests is marked as
223  failed.
224
225### The `@Precision` keyword
226
227The `@Precision` keyword specifies the comparison criterion used to
228compare the current values and the reference ones.
229
230~~~~{.cxx}
231@Precision 1.e-6;
232~~~~
233
234### The `@Test` keyword
235
236The `@Test` keyword specifies two files to compare which represents
237respectively the current simulated values and the reference ones.
238
239### The `@TestType` keyword
240
241The `@TestType` keyword specifies how the comparison between the
242simulated values and the reference values shall be performed.
243
244The following kind of comparison are available:
245
246- `Absolute`:
247- `Relative`:
248- `RelativeAndAbsolute`:
249- `Mixed`:
250- `Area`:
251
252### The `@Interpolation` keyword
253
254The `@Interpolation` keyword specifies how the reference values can be
255interpolated. The following interpolations are available:
256
257- `None`:
258- `Linear`:
259- `Spline`:
260- `LocalSpline`:
261
262# Description of the configuration files{#sec:tfel_check:configuration_files}
263
264Configuration files can be used to define:
265
266- substitution strings
267- available components
268
269The syntax of configuration file is loosely inspired by the `JSON`
270format and looks like:
271
272~~~~{.cxx}
273components : {"pleiades::python"};
274substitutions : {"python" : "python3.5"};
275~~~~
276
277# Default components {#sec:tfel_check:default_components}
278
279Some components are conditionally defined by `tfel-check`.
280
281- If the `python` bindings of the `TFEL` project have been enabled, the
282  following components are declared: `tfel::python` and
283  `mfront::python`.
284- If the `madnex` support has been enabled, the component `tfel::madnex`
285  is declared.
286
287For each `MFront`' interface for material properties, a component called
288`mfront::material_property::<name>_interface` is defined, where `<name>`
289shall be replaced by the name of the interface.
290
291For each behaviour interface, a component named
292`mfront::behaviour::<name>_interface` is declared, where `<name>` is the
293name of the interface.
294
295For each model interface, a component named
296`mfront::model::<name>_interface` is declared, where `<name>` is the
297name of the interface.
298
299Those default components can be listed using the
300`--list-default-components` command line options, as follows:
301
302~~~~{.cxx}
303$ tfel-check --list-default-components
304- tfel::python
305- mfront::python
306- tfel::madnex
307- mfront::material_property::C++_interface
308- mfront::material_property::Cpp_interface
309- mfront::material_property::Cxx_interface
310- mfront::material_property::Python_interface
311- mfront::material_property::c_interface
312- mfront::material_property::c++_interface
313- mfront::material_property::cpp_interface
314- mfront::material_property::cpptest_interface
315- mfront::material_property::cxx_interface
316- mfront::material_property::excel_interface
317- mfront::material_property::excel-internal_interface
318- mfront::material_property::gnuplot_interface
319- mfront::material_property::mfront_interface
320- mfront::material_property::octave_interface
321- mfront::material_property::python_interface
322- mfront::behaviour::generic_interface
323- mfront::model::mfront_interface
324~~~~
325