Loading tests to suite and running tests in Python Selenium

unittest.TestLoader :

The TestLoader class is used to create test suites from classes and modules in the python project.

Basically, it loads all the test cases into a pot, so that we can run all the test cases present in the pot. I have used Pot word to show that suite is nothing but the container.

allTests = unittest.TestLoader()

TestLoader class provides different methods to handle the loading of test cases.

loadTestsFromTestCase() :

loadTestsFromTestCase(TestClassName) method loads all the test cases from the given class, a test case instance is created for the method getTestCaseNames() which notifies each test cases present in the Test Class.

allTests = unittest.TestLoader()
suite = allTests.loadTestsFromTestCase(TestBing, TestCherCherTech)

TextTestRunner :

TextTestRunner class is the basic runner class present python, after loading all the methods using TestLoader and loadTestsFromTestCase, we have to start the run using run method present in the TextTestRunner class.

run method in TextTestRunner :

the run method starts the execution of the given suite, the run method takes a TestSuite or TestCase instance as a parameter (nothing but tests).

the run method creates the TestResults by calling some private methods present inside the TextTestRunner class. Prints the test results to the screen using stdout.

Complete program with TestLoader and TextTestRunner

After coupling the TestLoader and TextTestRunner, we have created a small piece of the program by combining test cases present in two test classes.

import unittest
from unittest.suite import TestSuite
from selenium import webdriver
# first test class
class TestBing(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=r'D:PATHchromedriver.exe')
        print("Browser Opened in first class")
    def test_open_bing(self):
        self.driver.get("https://bing.com")
        print("bing opened")
# second test class
class TestCherCherTech(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=r'D:PATHchromedriver.exe')
        print("Browser Opened in second class")
    def test_open_bing(self):
        self.driver.get("https://chercher.tech")
        print("Chercher tech opened")

if __name__ == "__main__":

	# create the suite from the test classes
    suite = TestSuite()
    # load the tests
    tests = unittest.TestLoader()

	# add the tests to the suite
    suite.addTests(tests.loadTestsFromTestCase(TestBing))
    suite.addTests(tests.loadTestsFromTestCase(TestCherCherTech))

    # run the suite
    runner = unittest.TextTestRunner()
    runner.run(suite)

running-suite-selenium-unittest-python

getTestCaseNames() :

getTestCaseNames(testCaseClass) method returns a sorted sequence of method names found within testCaseClass; test case class should be a subclass of TestCase.

import unittest
class Test_Me(unittest.TestCase):
    def test_Java(self):
        print("Java11")

    def test_Python(self):
        print("Python")

    def test_Typescript(self):
        print("Typescript")
if __name__ == "__main__":
    # load the tests
    tests = unittest.TestLoader()

   # add the tests to the suite
    alltestNames = tests.getTestCaseNames(Test_Me)

	# print test method present in test class
    print("Test case Names present  : " ,  alltestNames)

getTestCaseNames-python-unittest-selenium

loadTestsFromModule() :

loadTestsFromModule(module, pattern=None) method searches module for classes derived from TestCase and creates an instance of the class for each test method defined for the class.
If we load from the Module, then there is no need to load classes present in the module separately.

We can combine the Test classes (and test cases ) from multiple modules, below example shows loading tests from different modules.
Please note that I have created modules in different files.

*******************File1 module1*******************
import unittest
class Test_Module1(unittest.TestCase):
    def test_module1_WELCOME(self):
        print("module1 - welcome")

*******************File2 Module2*******************
import unittest
class TestModule2_HI(unittest.TestCase):
    def test_module2_hi(self):
        print("module2 - hi")
class TestModule2_HELLO(unittest.TestCase):

    def test_module2_hello(self):
        print("module2 - hello")

*******************File3 runner-module*******************
from unittest.suite import TestSuite
import unittest
from pythontest import module1, module2
if __name__ == "__main__":
    # create the suite from the test classes
    suite = TestSuite()
    # load the tests
    tests = unittest.TestLoader()
    # add the tests to the suite from modules
    suite.addTests(tests.loadTestsFromModule(module1))
    suite.addTests(tests.loadTestsFromModule(module2))

    # run the suite
    runner = unittest.TextTestRunner()
    runner.run(suite)

loadTestsFromModule-unittest-python-selenium

loadTestsFromName :

You can load the test cases based on the string provided, the string either could be a module or a class inside a module.

For writing module name you donot need any special import, automatically unittest imports the packages. We can also execute test cases present in a class alone, using the class name but while using the class name we have to modules name as well.

For example, if you have a module get_names_suite containing a class Test_Me with three test methods (test_Java(), test_Python(), and test_Typescript()), the specifier "get_names_suite.Test_Me" would cause this method to return a suite which will run all three test methods.

Using the specifier 'get_names_suite.Test_Me.test_Typescript' would cause it to return a test suite which will run only the test_Typescript() test method

************File namd & module Name is : get_names_suite***********
class Test_Me(unittest.TestCase):
    def test_Java(self):
        print("Java11")

    def test_Python(self):
        print("Python")

    def test_Typescript(self):
        print("Typescript")

************File namd & module Name is : load_name_test***********
import unittest
if __name__ == "__main__":
    print("Running using loadTestsFromName, module.Class.method")
    # create the suite from the test classes
    suite = TestSuite()
    # load the tests
    tests = unittest.TestLoader()
    # add the tests to the suite from modules
    suite.addTests(tests.loadTestsFromName("get_names_suite.Test_Me.test_Typescript"))

    # run the suite
    runner = unittest.TextTestRunner()
    runner.run(suite)

loadTestsFromName-unittest-python-selenium

loadTestsFromNames() :

This method is similar to loadTestsFromName but this method accepts more than one name (sequence of names), it returns all the test cases from the given module, test class names.

This method accepts different modules and classes from different modules.

import unittest
from unittest.suite import TestSuite
class Test_Tou(unittest.TestCase):
    def test_touch(self):
        print("touchme")

class Test_Ting(unittest.TestCase):
    def test_tingle(self):
        print("tingle me")
if __name__ == "__main__":
    # create the suite from the test classes
    suite = TestSuite()
    # load the tests
    tests = unittest.TestLoader()
    # add the tests to the suite from modules
    suite.addTests(tests.loadTestsFromNames(["load_name_test.Test_Ting", "module1", "module2"]))

    # run the suite
    runner = unittest.TextTestRunner()
    runner.run(suite)

loadTestsFromNames-unittest-pythn-selenium

testMethodPrefix() :

Sometimes we may write or a start the test methods with different prefix than test in such cases we can take help of this method to load the methods with different prefixes.

import unittest
from unittest.suite import TestSuite
class Test(unittest.TestCase):
    def test_sanity_hello(self):
        print("sanity test")

    def test_regression_hi(self):
        print("regression test")
if __name__ == "__main__":
    print("Running with test prefix")
    # create the suite from the test classes
    suite = TestSuite()
    # load the tests
    tests = unittest.TestLoader()
    tests.testMethodPrefix = "test_sanity"
    # add the tests to the suite from class 'Test'
    suite.addTests(tests.loadTestsFromTestCase(Test))
    # run the suite
    runner = unittest.TextTestRunner()
    runner.run(suite)

testMethodPrefix-unittest-python-selenium

sortTestMethodsUsing :

sortTestMethodsUsing method helps us to set, how the test cases should be executed in the test class.

getTestCaseNames() method first loads all the test methods into the pool, then sortTestMethodsUsing methods sort the tests present in the pool.

discover :

Find all the test modules by recursing into subdirectories from the specified start directory, and return a TestSuite object containing them. Only test files that match the pattern will be loaded. (Using shell style pattern matching.) Only module names that are importable (i.e. are valid Python identifiers) will be loaded.

All test modules must be importable from the top level of the project. If the start directory is not the top-level directory then the top-level directory must be specified separately.

Below program tries to run the test cases present from the top module but search begins with load_name_test, you can have matches in any module.

import unittest
from unittest.suite import TestSuite
import pythontest
from pythontest import module2
class Test_Tou(unittest.TestCase):
    def test_touch(self):
        print("touchme")

class Test_Ting(unittest.TestCase):
    def test_tingle(self):
        print("tingle me")
if __name__ == "__main__":
    print("Running using discover method")
    # create the suite from the test classes
    suite = TestSuite()
    # load the tests
    tests = unittest.TestLoader().discover("load_name_test", "load*test.py")
    # add the tests to the suite from modules

    # run the suite
    runner = unittest.TextTestRunner()
    runner.run(tests)

discover-unittest-python-selenium

suiteClass :

suites are nothing but the container of all the test methods

Create Test Suite

TestSuite :

TestSuite class represents an aggregation of individual test cases and test suites present in the python project.

The class provides the interface needed by the test runner to allow it to be run as any other test case.

Running a TestSuite instance is the same as iterating over the suite, running each test individually.

There are a few useful methods present in the Unittest.TestSuite to manipulate the test suite of test cases.

addTest(test) :

addTest method adds a test, test class, test suite to the TestSuite object.

import unittest
from unittest.suite import TestSuite
class Test_Tou(unittest.TestCase):
    def test_touch(self):
        print("touchme")

class Test_Ting(unittest.TestCase):
    def test_tingle(self):
        print("tingle me")
if __name__ == "__main__":
    print("Running using test suite with add test")
    # create the suite from the test classes
    suite = TestSuite()
    # load the test from test class
    suite.addTest(Test_Tou("test_touch"))

    # run the suite
    runner = unittest.TextTestRunner()
    runner.run(suite)

addTest-testsuite-unittest-python-selenium

addTests(tests) :

addTests method adds all the tests from an iterable of TestCase and TestSuite instances to this test suite in the unittest framework

We can load the test from the Modules, from the Test classes.

import unittest
from unittest.suite import TestSuite
from unittest.loader import TestLoader
from unittest.runner import TextTestRunner
class Test_Tou(unittest.TestCase):
    def test_touch(self):
        print("touchme")
    def test_tingle(self):
        print("tingle me")
if __name__ == "__main__":
    print("Running using test suite with add tests")
    # create the suite from the test classes
    suite = TestSuite()
    # will contains all tests
    tests = TestLoader()
    # load the test from test class
    suite.addTests(tests.loadTestsFromTestCase(Test_Tou))

    # run the suite
    runner = TextTestRunner()
    runner.run(suite)

addTests-testsuite-unittest-python-selenium

run(result) :

the run method runs the tests associated with this suite, collecting the result into the test result object passed as a result.

We have to pass TestResult object to this method as a parameter, I will give an example for this method in TestResult class as this method requires TestResult details as well.

countTestCases() :

countTestCases method returns the number of tests represented by the TestSuite test object, including all individual tests and sub-suites

import unittest
from unittest.suite import TestSuite
from unittest.loader import TestLoader
class Test_Tou(unittest.TestCase):
    def test_touch(self):
        print("touchme")
    def test_tingle(self):
        print("tingle me")
if __name__ == "__main__":
    # create the suite from the test classes
    suite = TestSuite()
    # will contains all tests
    tests = TestLoader()
    # load the test from test class
    suite.addTests(tests.loadTestsFromTestCase(Test_Tou))
    # number of test cases present
    print("No. of test cases present : ", suite.countTestCases())

countTestCases-unittest-python-selenium

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions

Protractor Training

new tutorial Please find the link for tomorrow's "Protractor" training. Training starts 10AM IST from 24-Aug-2019.

https://zoom.us/j/6584586238 First day of class(2 hours) is free.

Find the course content : View Content