前置步驟
Python版本:3.6.4
selenium版本:3.11.0
>>> import selenium
>>> help(selenium)
IDE:Pycharm
學習目的
- 掌握Python版本的selenium自動化技能,對所學的知識總結,可以作為日後工作的參考;
- 對學習的Python腳本編碼能力再磨練,實戰中學習;
- 為後續的跳槽作準備,說難聽點,不會編碼的測試,去哪都沒啥競争力
正式步驟
Step1:unittest架構中最核心的4個概念:test fixture(測試固件)、test case(測試用例)、test suite(測試套件)、test runner(測試運作器)
運作工作圖:
運作資料流:
- 一個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。
簡單示例:
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.測試用例執行後,結果順序是随機排序;
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
轉載于:https://www.cnblogs.com/wuzhiming/p/8858305.html