-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
There is currently a large amount of boilerplate and duplication associated with defining TDML tests with JUnit. To fix this, this adds two new traits that can be mixed in to the companion object and class associated with a JUnit test suite to greatly simplify test suite definitions. Test suites can now be defined with something like this: object MyTests extends TdmlSuite { val tdmlResource = "/resource/path/to/tests.tdml" } class MyTests extends TdmlTests { val tdmlSuite = MyTests @test def test1 = test @test def test2 = test @test def test3 = test } To allow use with older versions of Daffodil, this defaults to using creating a Runner with only the path parameter. This is sufficient for all known schema projects, since most Runner parameters can either be set directly in a TDML file (which is preferred), or are intended for use by Daffodil tests and should not be changed by schema projects. The sbt-plugin project will eventually be updated to include this as a dependency for DFDL Schema projects, but until that change is released, projects that want to use this new syntax should add the following to dependency to build.sbt file, in addition to any existing daffodil dependencies: libraryDependencies ++= Seq( "org.apache.daffodil" %% "daffodil-tdml-junit" % "<version>" % "test" intransitive() ) Where "<version>" is hardcoded to the first version that daffodil-tdml-junit is released for. The new library works with older versions of Daffodil, so by hardcoding the version and setting it as an intransitive dependency, it allows the library the be used with TDML tests even when testing older daffodil versions that do not publish the library. As we no longer need to support older versions of Daffodil and sbt-daffodil supports the new library, this will not be needed. DAFFODIL-2958
- Loading branch information
1 parent
0f3793a
commit a2c2eee
Showing
4 changed files
with
201 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
daffodil-tdml-junit/src/main/scala/org/apache/daffodil/junit/tdml/TdmlSuite.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.apache.daffodil.junit.tdml | ||
|
||
import java.io.File | ||
|
||
import org.apache.daffodil.tdml.Runner | ||
import org.apache.daffodil.tdml.TDMLTestNotCompatibleException | ||
|
||
import org.junit.AfterClass | ||
import org.junit.AssumptionViolatedException | ||
import org.junit.Rule | ||
import org.junit.rules.TestName | ||
|
||
/** | ||
* Mixin for a JUnit test suite companion object | ||
*/ | ||
trait TdmlSuite { | ||
|
||
/** | ||
* Resource path to the TDML file to use for this JUnit suite | ||
*/ | ||
val tdmlResource: String | ||
|
||
/** | ||
* Function to get the directory containing tdmlResource. Useful if createRunner is overridden | ||
* to use the Runner(dir, file, ...) factory method | ||
*/ | ||
def tdmlDir: String = new File(tdmlResource).getParent() | ||
|
||
/** | ||
* Function to get basename of tdmlResource. Useful if createRunner is overridden to use the | ||
* Runner(dir, file, ...) factory method | ||
*/ | ||
def tdmlFile: String = new File(tdmlResource).getName() | ||
|
||
/** | ||
* Default implementation to create a Runner using the tdmlResource. This function can be | ||
* overridden if additional options need to be passed to the Runner factory object, for | ||
* example to disable TDML validation. In most cases this should not be needed, since most | ||
* parameters should not be changed by normal schema tests, or can be defined in the TDML | ||
* file. | ||
*/ | ||
def createRunner(): Runner = Runner(tdmlResource) | ||
|
||
/** | ||
* Lazily build the runner when needed | ||
*/ | ||
final lazy val runner = createRunner() | ||
|
||
/** | ||
* Ensure all resources associated with the Runner (e.g. cached compiled schemas, parsed TDML | ||
* XML) to be freed once the test suite has completed | ||
*/ | ||
@AfterClass | ||
final def shutDown(): Unit = runner.reset | ||
} | ||
|
||
/** | ||
* Mixin for a JUnit test suite companion class | ||
*/ | ||
trait TdmlTests { | ||
|
||
/** | ||
* The companion object that contains the runner to be used for tests in this class | ||
*/ | ||
val tdmlSuite: TdmlSuite | ||
|
||
/** | ||
* Run a test from the runner with the same name as the JUnit test | ||
* | ||
* If a tdml test is not compatible with the DFDL implementation used for the test, we mark | ||
* test test as having violated an assumption. This prevents the test from generating a test | ||
* case failure, and instead it is marked as "skipped". | ||
*/ | ||
final def test: Unit = { | ||
try { | ||
tdmlSuite.runner.runOneTest(testName) | ||
} catch { | ||
case e: TDMLTestNotCompatibleException => | ||
throw new AssumptionViolatedException(e.getMessage, e) | ||
} | ||
} | ||
|
||
/** | ||
* Helper function to easily trace a test. This should only be used for debugging and running | ||
* a single test since "trace" modifies the state of the Runner causing all later tests in the | ||
* suite to run with trace enabled | ||
*/ | ||
final def trace: Unit = { | ||
tdmlSuite.runner.trace | ||
test | ||
Check warning on line 107 in daffodil-tdml-junit/src/main/scala/org/apache/daffodil/junit/tdml/TdmlSuite.scala Codecov / codecov/patchdaffodil-tdml-junit/src/main/scala/org/apache/daffodil/junit/tdml/TdmlSuite.scala#L106-L107
|
||
} | ||
|
||
/** | ||
* Helper function to get the current JUnit test name. Useful for some tests that might want | ||
* to provide special diagnostics about the test name | ||
*/ | ||
final def testName = _name.getMethodName | ||
|
||
/** | ||
* JUnit magic for setting the test name. Because the way scala turns vals into class members | ||
* + methods, the Rule annotation must be on a def | ||
*/ | ||
private val _name: TestName = new TestName() | ||
@Rule final def name = _name | ||
Check warning on line 121 in daffodil-tdml-junit/src/main/scala/org/apache/daffodil/junit/tdml/TdmlSuite.scala Codecov / codecov/patchdaffodil-tdml-junit/src/main/scala/org/apache/daffodil/junit/tdml/TdmlSuite.scala#L120-L121
|
||
} |
65 changes: 65 additions & 0 deletions
65
daffodil-tdml-junit/src/main/scala/org/apache/daffodil/junit/tdml/package.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.apache.daffodil.junit | ||
|
||
/** | ||
* <h3>Overview</h3> | ||
* | ||
* Provides two traits to reduce boilerplate related to defining TDML tests: | ||
* | ||
* [[TdmlSuite]]: mixed into a Junit test suite companion object ensures the TDML Runner is | ||
* created and cleaned up appropriately. Direct access to the runner is available, though most | ||
* tests should use the "test" or "trace" methods defined in [[TdmlTests]]. Note that a | ||
* TdmlSuite only supports a single TDML file and runner. If multiple are needed, additional | ||
* test class objects must be created. The TdmlSuite also only supports creating a Runner with | ||
* the default arguments. This is sufficient in most cases, but if a different runner is needed, | ||
* implementations can override the [[TdmlSuite.createRunner]] function. | ||
* | ||
* [[TdmlTests]]: contains [[TdmlTests.test]] and [[TdmlTests.trace]] helper functions to easily | ||
* run or trace tests without having to provide the runner or the test name. The JUnit test name | ||
* is used as the parameter passed to runOneTest (i.e. the name of the test in the TDML file). | ||
* The runner to use is the runner associated with the companion object, which must be set in | ||
* the [[TdmlTests.tdmlSuite]] val | ||
* | ||
* <h4>Examples</h4> | ||
* | ||
* The following example defines a JUnit test suite called "MyTests". The companion object mixes | ||
* in TdmlSuite and defines the tdmlResoruce to use for all tests in the suite. The companion | ||
* class mixes in TdmlTests and provides a reference to the companion object via the tdmlSuite | ||
* val, and defines a number of JUnit tests that each call the "test" method to run the TDML | ||
* test with the same name as the JUnit test. | ||
* {{{ | ||
* import org.apache.daffodil.junit.tdml.TdmlSuite | ||
* import org.apache.daffodil.junit.tdml.TdmlTests | ||
* | ||
* import org.junit.Tests | ||
* | ||
* object MyTests extends TdmlSuite { | ||
* val tdmlResource = "/resource/path/to/tests.tdml" | ||
* } | ||
* | ||
* class MyTests extends TdmlTests { | ||
* val tdmlSuite = MyTests | ||
* | ||
* @Test def test1 = test | ||
* @Test def test2 = test | ||
* @Test def test3 = test | ||
* } | ||
*}}} | ||
*/ | ||
package object tdml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters