Skip to content

Commit

Permalink
Merge: niunit: fix after/before test calls
Browse files Browse the repository at this point in the history
The specification of `nitunit` states that before and after methods can be called to initialize or clean test related things:

~~~nit
module my_test_suite

class MyTestSuite
    super TestSuite

    redef fun before_test do
          # complex things to set up the test
    end

    redef fun after_test do
          # complex things to tear down the test
    end

    fun test_foo do end
    fun test_bar do end
end
~~~

In the above example, `nitunit` will call the methods precisely in this order:

~~~nit
test_before
test_foo
test_after
test_before
test_bar
test_after
~~~

Before this PR, the before and after methods were only call if a redefinition of the before/after method exists locally in the test suite. Inheritance was not considered:

~~~nit
module my_test_suite

class TestBase
    super TestSuite

    redef fun before_test do # ...
    redef fun after_test do # ...
end

class MyTestSuite
    super TestBase

    fun test_foo do end
    fun test_bar do end
end
~~~

So the output was only:

~~~nit
test_foo
test_bar
~~~

This PR fixes that behavior.

Pull-Request: #1897
Reviewed-by: Jean Privat <jean@pryen.org>
  • Loading branch information
privat committed Dec 16, 2015
2 parents c86718e + 1431fad commit e47f39f
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 36 deletions.
55 changes: 19 additions & 36 deletions src/testing/testing_suite.nit
Expand Up @@ -58,15 +58,11 @@ class NitUnitTester
if not mclassdef.is_test then continue
if not suite_match_pattern(mclassdef) then continue
toolcontext.modelbuilder.total_classes += 1
var before_test = mclassdef.before_test
var after_test = mclassdef.after_test
for mpropdef in mclassdef.mpropdefs do
if not mpropdef isa MMethodDef or not mpropdef.is_test then continue
if not case_match_pattern(mpropdef) then continue
toolcontext.modelbuilder.total_tests += 1
var test = new TestCase(suite, mpropdef, toolcontext)
test.before_test = before_test
test.after_test = after_test
suite.add_test test
end
end
Expand Down Expand Up @@ -168,6 +164,7 @@ class TestSuite
fun to_xml: HTMLTag do
var n = new HTMLTag("testsuite")
n.attr("package", mmodule.name)
var failure = self.failure
if failure != null then
var f = new HTMLTag("failure")
f.attr("message", failure.to_s)
Expand All @@ -194,7 +191,13 @@ class TestSuite
end
# compile test suite
var file = test_file
var include_dir = mmodule.location.file.filename.dirname
var module_file = mmodule.location.file
if module_file == null then
toolcontext.error(null, "Error: cannot find module file for {mmodule.name}.")
toolcontext.check_errors
return
end
var include_dir = module_file.filename.dirname
var cmd = "{nitc} --no-color '{file}.nit' -I {include_dir} -o '{file}.bin' > '{file}.out' 2>&1 </dev/null"
var res = sys.system(cmd)
var f = new FileReader.open("{file}.out")
Expand Down Expand Up @@ -226,12 +229,6 @@ class TestCase
# `ToolContext` to use to display messages and find `nitc` bin.
var toolcontext: ToolContext

# `MMethodDef` to call before the test case.
var before_test: nullable MMethodDef = null

# `MMethodDef` to call after the test case.
var after_test: nullable MMethodDef = null

# Generate the test unit for `self` in `file`.
fun write_to_nit(file: Template) do
var name = test_method.name
Expand All @@ -240,9 +237,9 @@ class TestCase
file.addn "\t{name}"
else
file.addn "\tvar subject = new {test_method.mclassdef.name}.nitunit"
if before_test != null then file.addn "\tsubject.{before_test.name}"
file.addn "\tsubject.before_test"
file.addn "\tsubject.{name}"
if after_test != null then file.addn "\tsubject.{after_test.name}"
file.addn "\tsubject.after_test"
end
file.addn "end"
end
Expand Down Expand Up @@ -289,6 +286,7 @@ class TestCase
var n = new HTMLTag("system-out")
n.append "out"
tc.add n
var error = self.error
if error != null then
n = new HTMLTag("error")
n.attr("message", error.to_s)
Expand All @@ -306,12 +304,6 @@ redef class MMethodDef
# i.e. begins with "test_"
private fun is_test: Bool do return name.has_prefix("test_")

# Is the method a "before_test"?
private fun is_before: Bool do return name == "before_test"

# Is the method a "after_test"?
private fun is_after: Bool do return name == "after_test"

# Is the method a "before_module"?
private fun is_before_module: Bool do return mproperty.is_toplevel and name == "before_module"

Expand All @@ -323,27 +315,13 @@ redef class MClassDef
# Is the class a TestClass?
# i.e. begins with "Test"
private fun is_test: Bool do
var in_hierarchy = self.in_hierarchy
if in_hierarchy == null then return false
for sup in in_hierarchy.greaters do
if sup.name == "TestSuite" then return true
end
return false
end

# "before_test" method for this classdef.
private fun before_test: nullable MMethodDef do
for mpropdef in mpropdefs do
if mpropdef isa MMethodDef and mpropdef.is_before then return mpropdef
end
return null
end

# "after_test" method for this classdef.
private fun after_test: nullable MMethodDef do
for mpropdef in mpropdefs do
if mpropdef isa MMethodDef and mpropdef.is_after then return mpropdef
end
return null
end
end

redef class MModule
Expand Down Expand Up @@ -389,7 +367,12 @@ redef class ModelBuilder
if f != null then
test_file = f
else if not test_file.file_exists then
var include_dir = mmodule.location.file.filename.dirname
var module_file = mmodule.location.file
if module_file == null then
toolcontext.info("Skip test for {mmodule}, no file found", 2)
return ts
end
var include_dir = module_file.filename.dirname
test_file = "{include_dir}/{test_file}"
end
if not test_file.file_exists then
Expand Down
1 change: 1 addition & 0 deletions tests/nitunit.args
Expand Up @@ -6,3 +6,4 @@ test_doc2.nit --no-color -o $WRITE
test_nitunit3 --no-color -o $WRITE
test_nitunit_md.md --no-color -o $WRITE
test_doc3.nit --no-color -o $WRITE
test_nitunit4 --no-color -o $WRITE
16 changes: 16 additions & 0 deletions tests/sav/nitunit_args9.res
@@ -0,0 +1,16 @@
test_nitunit4/test_nitunit4.nit:22,2--25,4: ERROR: test_foo (in file .nitunit/gen_test_nitunit4.nit): Before Test
Tested method
After Test
Runtime error: Assert failed (test_nitunit4/test_nitunit4_base.nit:31)

DocUnits:
No doc units found
Entities: 10; Documented ones: 0; With nitunits: 0; Failures: 0

TestSuites:
Class suites: 1; Test Cases: 1; Failures: 1
<testsuites><testsuite package="test_nitunit4"></testsuite><testsuite package="test_nitunit4"></testsuite><testsuite></testsuite><testsuite package="test_nitunit4::nitunit4"></testsuite><testsuite package="test_nitunit4"><testcase classname="nitunit.test_nitunit4.test_nitunit4::TestTestSuite" name="test_nitunit4::TestTestSuite::test_foo"><system-err></system-err><system-out>out</system-out><error message="Before Test
Tested method
After Test
Runtime error: Assert failed (test_nitunit4&#47;test_nitunit4_base.nit:31)
"></error></testcase></testsuite><testsuite package="test_nitunit4::test_nitunit4_base"></testsuite><testsuite></testsuite></testsuites>
15 changes: 15 additions & 0 deletions tests/test_nitunit4/nitunit4.nit
@@ -0,0 +1,15 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Licensed 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.

module nitunit4
26 changes: 26 additions & 0 deletions tests/test_nitunit4/test_nitunit4.nit
@@ -0,0 +1,26 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Licensed 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.

module test_nitunit4 is test_suite

import test_nitunit4_base

class TestTestSuite
super SuperTestSuite

fun test_foo do
print "Tested method"
assert before
end
end
33 changes: 33 additions & 0 deletions tests/test_nitunit4/test_nitunit4_base.nit
@@ -0,0 +1,33 @@
# This file is part of NIT ( http://www.nitlanguage.org ).
#
# Licensed 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.

module test_nitunit4_base is test_suite

import test_suite

class SuperTestSuite
super TestSuite

var before = false

redef fun before_test do
print "Before Test"
before = true
end

redef fun after_test do
print "After Test"
assert false
end
end

0 comments on commit e47f39f

Please sign in to comment.