Python3 Selenium自動化web測試 ==> 第一節 起始點之Python單元測試框架 unittest

前置步驟


 

Python版本:3.6.4html

selenium版本:3.11.0python

>>> import selenium
>>> help(selenium)

IDE:Pycharmlinux

 

 

學習目的


 

  • 掌握Python版本的selenium自動化技能,對所學的知識總結,能夠做爲往後工做的參考;
  • 對學習的Python腳本編碼能力再磨練,實戰中學習;
  • 爲後續的跳槽做準備,說難聽點,不會編碼的測試,去哪都沒啥競爭力

 

正式步驟


 

Step1:unittest框架中最核心的4個概念:test fixture(測試固件)、test case(測試用例)、test suite(測試套件)、test runner(測試運行器)


 

運行工做圖:windows

運行數據流:框架

  • 一個TestCase的實例就是一個測試用例。什麼是測試用例呢?就是一個完整的測試流程,包括測試前準備環境的搭建(setUp),執行測試代碼(run),以及測試後環境的還原(tearDown)。元測試(unit test)的本質也就在這裏,一個測試用例是一個完整的測試單元,經過運行這個測試單元,能夠對某一個問題進行驗證。
  • 而多個測試用例集合在一塊兒,就是TestSuite,並且TestSuite也能夠嵌套TestSuite。
  • TestLoader是用來加載TestCase到TestSuite中的,其中有幾個loadTestsFrom__()方法,就是從各個地方尋找TestCase,建立它們的實例,而後add到TestSuite中,再返回一個TestSuite實例。
  • TextTestRunner是來執行測試用例的,其中的run(test)會執行TestSuite/TestCase中的run(result)方法。測試的結果會保存到TextTestResult實例中,包括運行了多少測試用例,成功了多少,失敗了多少等信息。
  • 而對一個測試用例環境的搭建和銷燬,是一個fixture。

簡單示例:less

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('FFF'.isupper(),msg='wrong flag')

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

 

運行結果:學習

F..
======================================================================
FAIL: test_isupper (__main__.TestStringMethods)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "F:/python_stack/python_autotest/demo.py", line 10, in test_isupper
    self.assertFalse('FFF'.isupper(),msg='wrong flag')
AssertionError: True is not false : wrong flag

----------------------------------------------------------------------
Ran 3 tests in 0.001s

FAILED (failures=1)

 

運行結果告訴咱們:測試

1.測試用例執行後,結果順序是隨機排序;ui

2.測試用例以test爲前綴;編碼

3.若是想單獨運行一個用例,點擊相應的測試用例代碼區域,右鍵點擊運行相應的方法

4,運行測試套件能夠點擊run(alt+shift+F10) 

 

Step2:test fixture之setUp() + tearDown() 和 setUpClass() 與 tearDownClass() 

setUp() + tearDown() :在每一個測試方法執行前以及執行後執行一次,setUp用來爲測試準備環境,tearDown用來清理環境,準備以後的測試

setUpClass() 與 tearDownClass():在全部case執行以前準備一次環境,並在全部case執行結束以後再清理環境

實例代碼:

import unittest

class TestStringMethods(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        #只執行一次,在全部用例開始前執行,通常用來預製數據,也能夠爲下發自動化task初始化
        print('setUpClass'+'\n')
    @classmethod
    def tearDownClass(cls):
        #只執行一次,在所用測試用例執行完畢後運行,通常用來清理測試環境
        print('tearDownClass'+'\n')

    def setUp(self):
        # 每一個用例都執行,在單個用例運行前執行
        print('準備開始執行用例'+'\n')

    def tearDown(self):
        #每一個用例都執行,在單個用例運行後執行
        print('清理此用例的初始化'+'\n')

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')
        print('test_upper'+'\n')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper(),msg='wrong flag')
        print('test_isupper'+'\n')

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)
        print('test_split'+'\n')

if __name__ == '__main__':
    unittest.main()

 

運行結果:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK
setUpClass

準備開始執行用例

test_isupper

清理此用例的初始化

準備開始執行用例

test_split

清理此用例的初始化

準備開始執行用例

test_upper

清理此用例的初始化

tearDownClass

 

 

 

Step3:test suite 的使用方法


 

test suite(測試套件)的做用是批量運行多個測試用例,此外還能夠作的操做是:

  • 調整測試用例執行順序
  • 多個test suite中的test case執行
  • (暫留)

實例1: 同一個文件中不一樣測試類中的測試用例加載到測試套件中

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

class MathMethods(unittest.TestCase):
    def test_sum(self):
        s = 'Python'
        self.assertNotEquals('python',s.islower())

if __name__ == '__main__':
    testcase1 = unittest.TestLoader().loadTestsFromTestCase(MathMethods)
    testcase2 = unittest.TestLoader().loadTestsFromTestCase(TestStringMethods)
    suite = unittest.TestSuite([testcase1,testcase2])
    #verbosity的參數爲0/1/2,2的回顯結果最詳細
    unittest.TextTestRunner(verbosity=2).run(suite)

 

運行結果:

test_sum (__main__.MathMethods) ... ok
test_isupper (__main__.TestStringMethods) ... ok
test_split (__main__.TestStringMethods) ... ok
test_upper (__main__.TestStringMethods) ... ok

----------------------------------------------------------------------
Ran 4 tests in 0.001s

OK

 

 

實例2:按照特定順序執行用例


 

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')
        print('test_upper')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())
        print('test_isupper')

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)
        print('test_split')


if __name__ == '__main__':
    print('單個單個添加測試用例')
    suite = unittest.TestSuite()
    suite.addTest(TestStringMethods('test_upper'))
    suite.addTest(TestStringMethods('test_split'))
    suite.addTest(TestStringMethods('test_isupper'))
    runner = unittest.TextTestRunner()
    runner.run(suite)
    print('同時添加多個測試用例')
    suite1 = unittest.TestSuite()
    suite1.addTests([TestStringMethods('test_split'),TestStringMethods('test_isupper'),TestStringMethods('test_upper')])
    runner2 = unittest.TextTestRunner()
    runner2.run(suite1)

 

 

 

Step4: 忽略某個測試用例不執行,也就是跳過某個用例不執行


 

import unittest
import sys

class TestStringMethods(unittest.TestCase):
    @unittest.skipIf('F'=='f','不知足判斷條件就執行')
    def test_upper2(self):
        self.assertEqual('foo'.upper(), 'FOO')
        print('test_upper2')


    @unittest.skipIf('F'=='f'.upper(),'知足判斷條件就不執行')
    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')
        print('test_upper')

    @unittest.skip('忽略此用例不執行')
    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())
        print('test_isupper')
#skipUnless表示若是系統名稱是linux,用例就忽略執行,提示用戶使用win,sys.platform返回操做系統平臺名稱
#Python startswith() 方法用於檢查字符串是不是以指定子字符串開頭
    @unittest.skipUnless(sys.platform.startswith('linux'),'we need windows')
    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)
        print('test_split')


if __name__ == '__main__':
    suite1 = unittest.TestSuite()
    suite1.addTests([TestStringMethods('test_upper2'),TestStringMethods('test_split'),TestStringMethods('test_isupper'),TestStringMethods('test_upper')])
    runner2 = unittest.TextTestRunner(verbosity=2)
    runner2.run(suite1)

 

運行結果:

test_upper2 (__main__.TestStringMethods) ... ok
test_upper2
test_split (__main__.TestStringMethods) ... skipped 'we need windows'
test_isupper (__main__.TestStringMethods) ... skipped '忽略此用例不執行'
test_upper (__main__.TestStringMethods) ... skipped '知足判斷條件就不執行'

----------------------------------------------------------------------
Ran 4 tests in 0.001s

OK (skipped=3)

 

 

Step5:將運行結果保存到文件中


 

import unittest
import sys

class TestStringMethods(unittest.TestCase):

    @unittest.skipIf('F'=='f','不知足判斷條件就執行')
    def test_upper2(self):
        self.assertEqual('foo'.upper(), 'FOO')
        print('test_upper2')


    @unittest.skipIf('F'=='f'.upper(),'知足判斷條件就不執行')
    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')
        print('test_upper')

    @unittest.skip('忽略此用例不執行')
    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())
        print('test_isupper')
#skipUnless表示若是系統名稱是linux,用例就忽略執行,提示用戶使用win,sys.platform返回操做系統平臺名稱
#Python startswith() 方法用於檢查字符串是不是以指定子字符串開頭
    @unittest.skipUnless(sys.platform.startswith('linux'),'we need windows')
    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)
        print('test_split')


if __name__ == '__main__':
    suite1 = unittest.TestSuite()
    suite1.addTests([TestStringMethods('test_upper2'),TestStringMethods('test_split'),TestStringMethods('test_isupper'),TestStringMethods('test_upper')])
    with open('result.txt','a+',encoding='utf-8') as f:
        runner2 = unittest.TextTestRunner(stream=f,verbosity=2)
        runner2.run(suite1)

 方法就是上述代碼所示

 

Step6: 使用HTMLTestRunner生成HTML格式測試報告


 

 測試腳本:

import unittest
import os
from HTMLTestRunner import HTMLTestRunner

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')
        print('test_upper')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())
        print('test_isupper')

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)
        print('test_split')


if __name__ == '__main__':
    report = os.path.join('D:/Python36/report/report.html')
    suite1 = unittest.TestSuite()
    suite1.addTests([TestStringMethods('test_split'),TestStringMethods('test_isupper'),TestStringMethods('test_upper')])
    with open(report,'wb') as f:
        runner2 = HTMLTestRunner(stream=f,title='Test Result',description='operator:admin',verbosity=2)
        runner2.run(suite1)

 

測試結果:

HTMLTestRunner腳原本自:https://blog.csdn.net/huilan_same/article/details/77944829

 

難點分析:


 

   1. Python3不少測試類不支持,沒有Python2那麼好找解決辦法

   2. 效率太慢,明天繼續

 

學習總結:


 

   磨磨蹭蹭終於開始作本身想作的事情了,但願半個月到一個月內,能夠輸出stepbystep的測試步驟,並且是Python3腳本,挺有意思的,就是公司沒有外網,坑啊

 

參考資料:


 

https://docs.python.org/3.6/library/unittest.html#  

https://blog.csdn.net/huilan_same/article/details/52944782

相關文章
相關標籤/搜索