Skip to content

Commit 047e525

Browse files
committed
Details on the test API
1 parent 5f7cf88 commit 047e525

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

RiGolo/accepted/tests-api.adoc

+23-8
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Assertion frameworks must be fully decoupled form the other components, to impro
5151
=== Suites definition and Extractor
5252

5353
A suite definition is a way to obtain a collection of suites to run.
54-
An _extractor_ is a function that takes a path where to look for golo test files and returns a collection of suites. Depending of the test framework, the file selection and suites construction can take several forms. This logic is encapsulated in the _extractor_ function.
54+
An _extractor_ is a function that takes a path-like footnote:[`java.io.File`, `java.nio.file.Path`, `String`,… see `Predefined.pathFrom`] where to look for golo test files and returns a collection of suites. Depending of the test framework, the file selection and suites construction can take several forms. This logic is encapsulated in the _extractor_ function.
5555
For instance, the _suite definition_ can be made by:
5656

5757
* using a fluent API (see for instance https://github.com/eclipse/golo-lang/pull/308[#308]),
@@ -75,6 +75,8 @@ Depending on the framework, this mean:
7575
. inspecting the modules to extract the associated suite (via reflexion, generation, invoking a known method, etc.),
7676
. building a collection of suites
7777

78+
Since the extractor may compile golo modules, its second argument must be a `org.eclipse.golo.compiler.GoloClassLoader`.
79+
7880
All those suite definition methods must be able to be used with the same test runner and reporter, since all they do is to return a collection of suites.
7981

8082
NOTE: Many known test frameworks allow to register methods to be executed before and after each test (a.k.a `setUp` and `tearDown`). It is the responsibility of the suite definition component to provide a way to define such methods, and to ensure that they will be correctly run, for instance by wrapping each test function under the hood. As far as the other components are concerned, a suite is just a bunch of function to run.
@@ -95,8 +97,9 @@ The collection of test results can be a lazy one, such that the test function is
9597

9698
=== Reporter
9799

98-
A _reporter_ is a function that takes a collection of suite results, “generate” a report, and returns the number of errors that occurred. Generating a report can mean printing a status on the console or creating a bunch of JUnit compatible Xml files for instance.
100+
A _reporter_ is a function that takes a collection of suite results, “generate” a report, and returns the number of errors that occurred. Generating a report can mean printing a status on the console or creating a bunch of JUnit compatible Xml files for instance. The reporting function thus takes two arguments: a collection of suite results and a string to specify the output. The semantic of this string depends on the reporter (directory, file, …), with the convention that `"-"` means standard output.
99101

102+
[[packages]]
100103
=== Packages
101104

102105
Should we include one or several alternative implementations for these components in the standard library, the modules must be well organized. The following namespaces are proposed:
@@ -108,7 +111,7 @@ Should we include one or several alternative implementations for these component
108111

109112
For instance, a simple runner module could be located at `gololang.testing.runners.SimpleTestRunner`, a JUnit like reporter at `gololang.testing.reporters.JUnitXmlReporter` and a fluent suite building API at `gololang.testing.suites.DescribeIt`.
110113

111-
Some common utilities could be provided, among others:
114+
Some common utilities could be provided (e.g. in `gololang.testing.Utils`), among others:
112115

113116
* function to walk the tree of file looking for specific module (can take a filtering function as parameter),
114117
* function to ease the compilation of a golo file (since this will be done by the extractor),
@@ -134,20 +137,22 @@ import my.testing.MySuperSuiteExtractor
134137
import other.testing.framework.ThePrettyReporter
135138
import someone.else.FancyTestRunner
136139
140+
import gololang.testing.Utils
141+
137142
function main = |args| {
138-
System.exit(reporter(runner(extractor(args: get(0)))))
143+
System.exit(reporter(runner(extractor(args: get(0), currentClassLoader())), "-"))
139144
}
140145
----
141146

142-
Since the actions to take are known in advance, it would be desirable to create a dedicated `golo test` command. This command must thus take the three functions as parameters, as well as the starting directory to search for test modules (defaulting to the current one). Two ways to define the functions to use should be possible:
147+
Since the actions to take are known in advance, it would be desirable to create a dedicated `golo test` command. This command must thus take the functions as parameters, as well as the starting directory to search for test modules (defaulting to the current one), and the output (defaulting to standard output). Two ways to define the functions to use should be possible:
143148

144149
* using command line options, e.g.:
145150
[source,bash]
146151
----
147152
golo test \
148153
--reporter=other.testing.framework.ThePrettyReporter::reporter \
149154
--runner=someone.else.FancyTestRunner::runner \
150-
--extractor=my.testing.MySuperSuiteExtractor::extractor \
155+
--extractors=my.testing.MySuperSuiteExtractor::extractor \
151156
src/
152157
----
153158

@@ -157,7 +162,7 @@ golo test \
157162
export GOLO_OPTS='
158163
-Dgolo.testing.reporter="other.testing.framework.ThePrettyReporter::reporter"
159164
-Dgolo.testing.runner="someone.else.FancyTestRunner::runner"
160-
-Dgolo.testing.extractor="my.testing.MySuperSuiteExtractor::extractor"'
165+
-Dgolo.testing.extractors="my.testing.MySuperSuiteExtractor::extractor"'
161166
golo test src/
162167
----
163168

@@ -167,14 +172,24 @@ The only task of the `test` command is thus to get the functions (e.g. using `Pr
167172
[source,java]
168173
----
169174
try {
170-
System.exit(reporter.invoke(runner.invoke(extractor.invoke(path))));
175+
System.exit(reporter.invoke(runner.invoke(extractor.invoke(path, classLoader)), output));
171176
} catch (Throwable t) {
172177
// ...
173178
}
174179
----
175180

176181
To ease the integration of the command in automated test tools, the command _must_ exit with the number of failed tests as status, as returned by the reporter function.
177182

183+
The function specification use the same kind of notations as literal Golo function references, with some additional conventions:
184+
185+
* when just a function name is given, the module is the one described in <<packages,Packages>>,
186+
* when just a module name is given, the function names will be: `extract`, `run`, and `report`.
187+
188+
For instance, an option `--reporter my.custom.Reporter` will use the function `my.custom.Reporter::report`, and `--reporter simple` will use `gololang.testing.reporters::simple`.
189+
190+
Sensible default runner and reporter functions should be defined as soon as implementations are present in the standard library.
191+
192+
178193
== Rationale
179194

180195
The main idea is to make each components as loosely coupled as possible. This will allows for alternative implementations and easy integration an reusing of these components.

0 commit comments

Comments
 (0)