Automated test and framework (selenium+python) unittest structure and HTML test report

Posted by ashebrian on Mon, 20 Dec 2021 19:47:00 +0100

PART 3: write test units using Unittest (WebDriver + unittest)

1. Unittest

unittest unit test framework:

Commonly known as PyUnit, it is inspired by JUnit, which is widely used in Java program development; We can use unittest to create a comprehensive test suite for any project;

unittest enables us to create test cases, test suites and test fixtures;

unittest component:

1) Test Fixture:

Using the test fixture, you can define the preparation work before single or multiple test execution and the cleaning work after test execution;

2) Test Case:

The smallest unit to execute the test in unittest. Verify the response obtained after a specific set of operations and inputs by verifying the assert method provided by unittest;

unittest provides a basic class called TestCase, which can be used to create test cases;

3) Test suite:

A test suite is a collection of multiple tests or test cases. It is a set of tests created for the corresponding functions and modules of the tested program. The test cases in a test suite will be executed together;

4) Test Runner:

The test executor is responsible for test execution scheduling and generating test results to users;

The test executor can use the graphical interface, text interface or specific return value to display the test execution results;

5) Test Report:

The test report shows the summary of success or failure status of all execution cases; Including the expected and actual results of failed test steps, as well as the summary of overall operation status and operation time;  
Original link: https://blog.csdn.net/baby_hua/article/details/80571109

The general test is divided into three parts: an initialization precondition, an execution function operation, and an assertion to verify whether the actual result is consistent with the expected result.

2. Implement a simple Test case with a Test case class

2.1 create a Python unit file

2.2 copy the following code into the file.

   
  1. # -*- coding:utf-8 -*-
  2. import unittest
  3. from selenium import webdriver
  4. class SearchTest(unittest.TestCase):
  5. def setUp(self):
  6. self.driver = webdriver.Firefox()
  7. self.driver.implicitly_wait( 15)
  8. self.driver.maximize_window()
  9. self.driver.get( 'http://www.baidu.com')
  10. def test_search_by_category1(self):
  11. self.search_field = self.driver.find_element_by_id( "kw")
  12. self.search_field.clear()
  13. self.search_field.send_keys( 'selenium2')
  14. self.search_field.submit()
  15. products = self.driver.find_elements_by_xpath( "//div[contains(@class, 'c-abstract')]")
  16. self.assertEqual( 10, len(products))
  17. def test_search_by_category2(self):
  18. self.search_field = self.driver.find_element_by_id( "kw")
  19. self.search_field.clear()
  20. self.search_field.send_keys( 'selenium2')
  21. self.search_field.submit()
  22. products = self.driver.find_elements_by_xpath( "//div[contains(@class, 'c-abstract')]")
  23. self.assertEqual( 10, len(products))
  24. def tearDown(self):
  25. self.driver.quit()
  26. if __name_ _ == '__main__':
  27. unittest.main(verbosity= 2)

In test_ search_ by_ Test can be added below the use case of category 1_ search_ by_ Category2, running is to execute two cases

Assertion: the TestCase class of unittest provides many practical methods to verify whether the expected results are consistent with the actual results;

assertEqual(a, b [, msg]); assertNotEqual(a, b [, msg]);

assertTrue(x [, msg]); assertFalse(x [, msg]);

assertIsNot(a, b [, msg]);

assertRaises(exc, fun, *args, **kwds);

......
 

3. A set of tests with TestSuite components

Using the TestSuites feature of unittest, you can form different tests into a logical group, then set a unified test suite and execute it through a command; It is implemented through TestSuites, TestLoader and TestRunner classes;

Rename the previous script testcase1 Py, and then create a new script testcase2 py.

   
  1. # -*- coding:utf-8 -*-
  2. import unittest
  3. from selenium import webdriver
  4. from selenium.common.exceptions import NoSuchElementException
  5. from selenium.webdriver.common.by import By
  6. class SearchTestHomePage(unittest.TestCase):
  7. @classmethod
  8. def setUpClass(cls):
  9. cls.driver = webdriver.Firefox()
  10. cls.driver.implicitly_wait( 15)
  11. cls.driver.maximize_window()
  12. cls.driver.get( 'http://www.baidu.com')
  13. def test_search_by_category(self):
  14. self.assertTrue(self.is_element_present(By.ID, "kw"))
  15. def test_search_by_category1(self):
  16. self.search_field = self.driver.find_element_by_id( "kw")
  17. self.search_field.clear()
  18. self.search_field.send_keys( 'selenium')
  19. self.search_field.submit()
  20. products = self.driver.find_elements_by_xpath( "//div[contains(@class, 'c-abstract')]")
  21. self.assertEqual( 10, len(products))
  22. @classmethod
  23. def tearDownClass(cls):
  24. cls.driver.quit()
  25. def is_element_present(self, how, what):
  26. """"""
  27. try:
  28. self.driver.find_element(by=how, value=what)
  29. except NoSuchElementException as e:
  30. return False
  31. return True
  32. if __name__ == '__main__':
  33. unittest.main(verbosity= 2)

Create a new TestSuite Py file is as follows

   
  1. # -*- coding:utf-8 -*-
  2. import unittest
  3. from TestCase1 import SearchTest
  4. from TestCase2 import SearchTestHomePage
  5. search_test = unittest.TestLoader().loadTestsFromTestCase(SearchTest)
  6. search_test_homepage = unittest.TestLoader().loadTestsFromTestCase(SearchTestHomePage)
  7. smoke_tests = unittest.TestSuite([search_test, search_test_homepage])
  8. unittest.TextTestRunner(verbosity= 2).run(smoke_tests)

View run results:

You can also see the reasons for individual case fail ures

4. Extend and generate test reports in HTML format

Generate an execution result of all tests and send it to other personnel in the same group as a report; Therefore, we need a more friendly test report, which can not only view the test results, but also go deep into all details; We can use the extension of unittest HTMLTestRunner To achieve.

4.1 modify the code of TestSuite file as follows:

   
  1. # -*- coding:utf-8 -*-
  2. import unittest
  3. import HTMLTestRunner
  4. import os
  5. from TestCase1 import SearchTest
  6. from TestCase2 import SearchTestHomePage
  7. from datetime import date
  8. now = date.today()
  9. datestr = now.strftime( '%m-%d-%y')
  10. dir = os.getcwd()
  11. search_test = unittest.TestLoader().loadTestsFromTestCase(SearchTest)
  12. search_test_homepage = unittest.TestLoader().loadTestsFromTestCase(SearchTestHomePage)
  13. smoke_tests = unittest.TestSuite([search_test, search_test_homepage])
  14. filepath = dir + "/SmokeTestReport{}.html".format(datestr)
  15. with open(filepath, 'wb') as outfile:
  16. runner = HTMLTestRunner.HTMLTestRunner(stream=outfile, title= 'Title: Test Report', description= 'Des:Smoke Tests')
  17. runner.run(smoke_tests)
  18. #unittest.TextTestRunner(verbosity=2).run(smoke_tests)

However, you will find that you cannot Install HTMLTestRunner, so that you cannot import this class

4.2 it can be achieved by the following methods.

install HTMLTestRunner in python 3 

1) Download htmltestrunner. Com from Py, and put this file under the project, or build an htmltestrunner Py file, copy the code in

         http://tungwaiyip.info/software/HTMLTestRunner.html

2) You can import HTMLTestRunner and still encounter the following problems. You can modify the following places

  • Question 1: No module named StringIO
  • Reason: there is no StringIO module in python 3. Here we need to use io this module instead.
  • Solution: change the name introduced in line 94 from import StringIO to import io. Accordingly, line 539 self outputBuffer = StringIO. Stringio() should be changed to self outputBuffer = io. BytesIO()
  • Question 2: AttributeError: 'dict' object has no attribute 'has_key'
  • Reason: object s of python 3 dictionary type no longer support has_key function, we need to use in to traverse.
  • Solution: navigate to line 642, if not rmap has_ Key (CLS): if not cls in rmap:
  • Question 3: 'str' object has no attribute 'decode'
  • Reason: in the operation of characters in Python 3, the decode has been removed.
  • Solution: go to line 772 and change ue = e.decode('latin-1 ') directly to ue = e.
  • In addition 766, there is a similar uo=o. decode ('latin-1 '), which is changed to uo=o;
  • Question 4: TypeError: can't concat bytes to str
  • Reason: locate and report 778 lines of escape(uo+ue). This is because when we assign value to uo above, we follow the else process. Uo is assigned a value of bytes. The bytes type cannot be directly converted to str type. Therefore, we need to convert the bytes type to str type before assigning value to uo.
  • Solution: modify uo = O in line 768 and directly change it to uo = o.decode('utf-8 '). In addition, 774 has a similar "ue = e", which is changed to "ue = e.decode('utf-8 ').
  • Question 5: typeerror: Unsupported operand type (s) for > >: 'builtin_ function_ or_ method' and 'RPCProxy'
  • Reason: Python 3} does not support print > > sys Stderr. If the output stream is defined here, print("This is print str",file=sys.stderr) is used.
  • Solution: locate line 631 and modify the print statement. It turned out to be print > > sys Stderr, '\ ntime elapsed:% s'% (self. StopTime self. Starttime), can be changed to print (' \ ntime elapsed:% s'% (self. StopTime self. Starttime), file = sys stderr)
  • Q6: TypeError: 'str' does not support the buffer interface
  • Reason: locate the problem. The problem lies in line 118. Here s is str type. We need to convert the passed s into bytes.
  • Solution: go to line 118 and put "self" fp. Modify write (s) to self fp. Write (bytes (s, 'UTF-8').

From: https://www.cnblogs.com/wangjunjiehome/articles/9262061.html

You can also directly download the modified htmltestrunner Py, open the following link

       https://download.csdn.net/download/qq_24047585/12402608 

3) Add htmltestrunner The PY file can be placed in the project folder or the python 38 directory.

4.3 viewing generated reports

In this way, you can get a simple report in HTML~~~

**Automated testing and framework (selenium+python)**

Topics: Python unittest