Unit Test - Part 2
Skipping tests and expected failures
Skip Test
Unittest
supports skipping individual test methods and even whole classes of tests conditionally
as well as unconditionally. Skipping
a test is simply a matter of using the skip() decorator or one of its
conditional variants, calling TestCase.skipTest() within a setUp() or test
method, or raising SkipTest directly.
Basic
skipping method unconditionally.
import unittest
class SkipTestExample(unittest.TestCase):
@unittest.skip("Method not yet ready for execution")
def test_Skipp(self):
print("This is unconditionally Skipping Example")
def test_print(self):
print("This is will execute because skip method is not using")
if __name__=="__main__":
unittest.main()
When the
above script is executed, the following result is displayed
Only
“test_print()” method will execute and test_skip() method will not execute.
The following
decorators are implement test skipping:
1.
@unittest.skipIf(condition, reason)
Skip
the decorated test if condition is true.
Below is the
example for skipIf decorators
import unittest
class SkipTestExample(unittest.TestCase):
a=10
b=20
def test_print(self):
print("This is will execute because skip method is not using")
@unittest.skipIf(a<b,"Skip this method if condition is met")
def test_skipif(self):
print("This method will execute only when a is greater then b else it will skip")
if __name__=="__main__":
unittest.main()
class SkipTestExample(unittest.TestCase):
a=10
b=20
def test_print(self):
print("This is will execute because skip method is not using")
@unittest.skipIf(a<b,"Skip this method if condition is met")
def test_skipif(self):
print("This method will execute only when a is greater then b else it will skip")
if __name__=="__main__":
unittest.main()
output will be
2.
@unittest.skipUnless(condition, reason)
Skip the decorated test unless condition is
true.
Below is the
script for skipUnless decorator
import unittest
class
SkipTestExample(unittest.TestCase):
a=10
b=20
def test_print(self):
print("This is will execute because skip method is not using")
@unittest.skipUnless(a==0,"Skipping this method if condition is not met")
def test_skipif(self):
print("This method will execute only when a is not equal to 0 else it will skip")
if __name__=="__main__":
unittest.main()
a=10
b=20
def test_print(self):
print("This is will execute because skip method is not using")
@unittest.skipUnless(a==0,"Skipping this method if condition is not met")
def test_skipif(self):
print("This method will execute only when a is not equal to 0 else it will skip")
if __name__=="__main__":
unittest.main()
Output will
be
Expected Failure
It supports
marking a test as an “expected failure,” a test that is broken and will fail,
but shouldn’t be counted as a failure on a TestResult.
The following
example demonstrates the use of expected failure.
import unittest
class ExpectedFailureExample(unittest.TestCase):
@unittest.expectedFailure
def test1_expectedFaliure(self):
a=5
b=6
self.assertEqual(a+b,10)
def test2_expectedFaliure(self):
a = 5
b = 6
self.assertEqual(a + b, 10)
def test3(self):
a = 5
b = 6
self.assertEqual(a + b, 11)
if __name__=="__main__":
unittest.main()
class ExpectedFailureExample(unittest.TestCase):
@unittest.expectedFailure
def test1_expectedFaliure(self):
a=5
b=6
self.assertEqual(a+b,10)
def test2_expectedFaliure(self):
a = 5
b = 6
self.assertEqual(a + b, 10)
def test3(self):
a = 5
b = 6
self.assertEqual(a + b, 11)
if __name__=="__main__":
unittest.main()
Output will
be
Test Suite Loading and running tests
To achieve this, unittest
supports the following important concepts.
test suite −
This is a collection of test cases, test suites, or both. This is used to
aggregate tests that should be executed together. Test suites are implemented
by the TestSuite class.
testLoader-The
TestLoader class is used to create test suites from classes and modules.
Normally, there is no need to create an instance of this class the unittest
module provides an instance that can be shared as unittest.defaultTestLoader.
test runner −
This is a component which organize the execution of tests and provides the results
to end user. The runner may use a graphical interface, a textual interface, or
return a special value to indicate the results of executing the tests.
Below is the example.
create simpleTestCase_1.py
# Test Suite
import unittest
class
simpleTest1(unittest.TestCase):
def setUp(self):
print("Simple Test at Test level
from simpleTest1")
def tearDown(self):
print("Simple Test TearDown from simpleTest1")
@unittest.expectedFailure
def testfirst(self):
self.assertTrue(10==20)
def tearDown(self):
print("Simple Test TearDown from simpleTest1")
@unittest.expectedFailure
def testfirst(self):
self.assertTrue(10==20)
def testSecond(self):
print("simple TestSecond from simpleTest1")
if __name__=="__main__":
unittest.main(verbosity=2)
create simpleTestCase_2.py
import unittest
class
simpleTest2(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("SetUp is class level simpleTest2")
@classmethod
def setUpClass(cls):
print("SetUp is class level simpleTest2")
@classmethod
def tearDownClass(cls):
print("tearDown is at class level simpleTest2")
def tearDownClass(cls):
print("tearDown is at class level simpleTest2")
def setUp(self):
print("\nTestlevel")
def testsimple(self):
print("simple Test simpleTest2")
print("\nTestlevel")
def testsimple(self):
print("simple Test simpleTest2")
def testsimple1(self):
print("simpleTest2 simpleTest2")
print("simpleTest2 simpleTest2")
if __name__=="__main__":
unittest.main(verbosity=2)
we’ll use the TestSuite class for defining and running the test
suite. And we can add multiple test cases into it. Also, apart from the
TestSuite class, we need to use TestLoader and TextTestRunner classes to create
and run a test suite.
Create SimpleTestRunner.py
import unittest
from simpleTestCase_1 import simpleTest1
from simpleTestCase_2 import simpleTest2
from simpleTestCase_1 import simpleTest1
from simpleTestCase_2 import simpleTest2
simple1=unittest.TestLoader().loadTestsFromTestCase(simpleTest1)
simple2=unittest.TestLoader().loadTestsFromTestCase(simpleTest2)
test_suite=unittest.TestSuite([simple1,simple2])
unittest.TextTestRunner(verbosity=2).run(test_suite)
unittest.TextTestRunner(verbosity=2).run(test_suite)
output will be
Generate HTML Test Suite Execution Report
By default, the Python Unittest library send out the test output
on the terminal console. If you want to share the results with management or stakeholders,
console logs aren’t the appropriate way.
So, you need to generate human readable presentation of results in
details what you required. Since the unit test library doesn’t have the ability
to produce such a report, so you should use the HTMLTestRunner extension.
HtmlTest runner is a unittest test runner that saves results in a
human-readable HTML format.
Note: for that you should
install “html-testRunner” package.
HtmlTestRunner can also be
used with test suites; just create a runner instance and call the run method
with your suite.
Create SimpleHTMLTestRunner.py
import unittest
import HtmlTestRunner
from simpleTestCase_1 import simpleTest1
from simpleTestCase_2 import simpleTest2
simple1=unittest.TestLoader().loadTestsFromTestCase(simpleTest1)
simple2=unittest.TestLoader().loadTestsFromTestCase(simpleTest2)
test_suite=unittest.TestSuite([simple1,simple2])
from simpleTestCase_2 import simpleTest2
simple1=unittest.TestLoader().loadTestsFromTestCase(simpleTest1)
simple2=unittest.TestLoader().loadTestsFromTestCase(simpleTest2)
test_suite=unittest.TestSuite([simple1,simple2])
outfile="C:\\PycharmProjects\\TestReport"
runner=HtmlTestRunner.HTMLTestRunner(outfile)
runner.run(test_suite)
runner=HtmlTestRunner.HTMLTestRunner(outfile)
runner.run(test_suite)
This is a sample of the results from the template that came by
default with the runner.
Note: By default, separate reports will be produced for each TestCase.
Combining Reports into a Single
Report
By default, separate reports will be produced for each TestCase.
The combine_reports boolean kwarg can be used to tell HTMLTestRunner to instead
produce a single report:
Create SimpleHTMLTestRunner_combined.py
import unittest
import HtmlTestRunner
from simpleTestCase_1 import simpleTest1
from simpleTestCase_2 import simpleTest2
simple1=unittest.TestLoader().loadTestsFromTestCase(simpleTest1)
simple2=unittest.TestLoader().loadTestsFromTestCase(simpleTest2)
test_suite=unittest.TestSuite([simple1,simple2])
from simpleTestCase_2 import simpleTest2
simple1=unittest.TestLoader().loadTestsFromTestCase(simpleTest1)
simple2=unittest.TestLoader().loadTestsFromTestCase(simpleTest2)
test_suite=unittest.TestSuite([simple1,simple2])
outfile="C:\\PycharmProjects\\TestReport"
runner=HtmlTestRunner.HTMLTestRunner(outfile,combine_reports=True)
runner=HtmlTestRunner.HTMLTestRunner(outfile,combine_reports=True)
runner.run(test_suite)
This is a sample of the combine reports of all the running
testcases.
Setting a filename
By default the name of the HTML file(s) produced will be created
by joining the names of each test case together. The report_name kwarg can be
used to specify a custom filename. For example, the following will produce a
report file called "MyReport.html":
runner=HtmlTestRunner.HTMLTestRunner(outfile,combine_reports=True,report_name="MyReport",add_timestamp=False)
Note:
if you are not add “add_timestamp=false” kwarg ,time stamp will
concatenate with your custom file name
Ex: MyReport_2019-11-04_14-19-24.html
if you are add
“add_timestamp=false” kwarg ,time stamp will not concatenate with your custom file name
Ex: MyReport.html
Custom Templates
title: This is the report title - by default this is
"Unittests Results" but can be changed using the report_title kwarg
Ex: runner=HtmlTestRunner.HTMLTestRunner(outfile,report_title="Regression",combine_reports=True)
Comments
Post a Comment