Appium python unittest pageobject如何實現加載多個case
學習了Appium python項目施展的課程小夥伴都會有一個疑問,說現在所有的case都是通過一個suite進行一個方法一個方法進行添加的,但是在實際過程中我們不希望這樣,我們做出來的功能是這樣:
suite = unittest.TestSuite() suite.addTest(CaseTest("test_02",parame=i)) unittest.TextTestRunner().run(suite)
這個是我們現在做的現狀,但是我們希望的是:
discover = unittest.defaultTestLoader.discover(case_dir,pattern=‘test_*.py‘) unittest.TextTestRunner().run(discover)
那我們如何才能夠我們做出來的換成我們想要的呢?我這裏告訴大家答案,你現在還不行!
為什麽這麽說呢?首先我們需要知道一個前提,我們現在拿到的discover是什麽?我們運行機制是什麽?先看下面兩個簡單代碼:
#coding=utf-8 import unittest class StudyTest(unittest.TestCase): def test_study01(self): print("studytest de 01") def test_study02(self): print("studytest de 02")
#coding=utf-8 import unittest class StudyTest01(unittest.TestCase): def test_study001(self): print("studytest01 de 001") def test_study002(self): print("studytest01 de 002") if __name__ == ‘__main__‘: test_dit = ‘./‘ discovre = unittest.defaultTestLoader.discover(test_dit,pattern=‘study_*.py‘) print(discovre) runner = unittest.TextTestRunner() runner.run(discovre)
上面兩個代碼我們簡單的實現了discover的實現,這裏我們是不是想要的就是這樣呢?但是為什麽說不行呢?至少你現在不行,首先看一下我們打印的discover是什麽。
<unittest.suite.TestSuite tests=[
<unittest.suite.TestSuite tests=[]>,
<unittest.suite.TestSuite tests=[]>,
<unittest.suite.TestSuite tests=[]>,
<unittest.suite.TestSuite tests=[
<unittest.suite.TestSuite tests=[]>,
<unittest.suite.TestSuite tests=[<case.study_test.StudyTest testMethod=test_study01>, <case.study_test.StudyTest testMethod=test_study02>]>]>,
<unittest.suite.TestSuite tests=[
<unittest.suite.TestSuite tests=[<case.study_test01.StudyTest01 testMethod=test_study001>, <case.study_test01.StudyTest01 testMethod=test_study002>]>]>,
<unittest.suite.TestSuite tests=[]>,
<unittest.suite.TestSuite tests=[]>,
<unittest.suite.TestSuite tests=[]>,
<unittest.suite.TestSuite tests=[]>]>
通過上面的打印我相信大家能夠看出來,我把格式整理之後我們所謂的discover其實就是我們所有的case的一個集合(這裏這麽說不恰當,但是更容易理解),這裏面是我們的用例,這個時候我只要去運行我們的case就可以了。那麽問題來了,我們需要傳遞參數如何傳遞?是不是發現這樣我們沒辦法傳遞參數?然後小夥伴們通過前面的課程發現了這樣一個方法,課程中的方法我們講到了
一個全局變量,但是這個我們需要一個方法一個方法添加,這不是我們的目的,所以我們可以通過查找在網上也能夠找到方法,看一下代碼:
#-*- coding: utf-8 -*-
#author: mushishi
#Date:2018年8月26日
import unittest
class ParametrizedTestCase(unittest.TestCase):
"""
繼承之後,重寫一下,把這個參數傳遞到unittest裏面
"""
def __init__(self, methodName=‘runTest‘, param=None):
super(ParametrizedTestCase, self).__init__(methodName)
self.param = param
@staticmethod
def parametrize(testcase_klass, param=None):
testloader = unittest.TestLoader()
testnames = testloader.getTestCaseNames(testcase_klass)
suite = unittest.TestSuite()
for name in testnames:
suite.addTest(testcase_klass(name, param=param))
return suite
class TestOne(ParametrizedTestCase):
def test_first(self):
print (‘param =‘, self.param)
self.assertEqual(1, 1)
def test_two(self):
print (‘param =‘, self.param)
self.assertEqual(2, 2)
if __name__ == ‘__main__‘:
suite = unittest.TestSuite()
suite.addTest(ParametrizedTestCase.parametrize(TestOne, param=1))
suite.addTest(ParametrizedTestCase.parametrize(TestOne, param=2))
unittest.TextTestRunner(verbosity=2).run(suite)
通過上面這個方法是不是發現可以傳遞參數。但是可能很多小夥伴不知道什麽意思,沒事,我們仔細看一下代碼的拆分,畢竟這個代碼網上很多,但是很多小夥伴不知道為什麽,而且很多小夥伴不知道這個怎麽和我們的需求串聯起來,也不知道和我們這個有什麽關系,我們應該怎麽處理。我們看下面:
suite = unittest.TestSuite() suite.addTest(ParametrizedTestCase.parametrize(TestOne, param=1))
首先我們看我們的程序執行入口,在我們這個入口我們知道我們有了一個容器,這個時候需要往容器裏面添加case,這個case的添加我們是有條件的,我們首先需要知道這個case在哪一個class裏面,也就是說我們添加我們case的時候是把class和方法一起添加的,那這個和我們上面說的通過拿到py文件,然後想參數話有啥關系?首先需要提出一個疑問:
1、我們前面的代碼只是拿到了我們所有的case,並沒有拿到我們的class name,系統只是通過py文件去拿裏面case然後添加到一個集合裏
2、我們後面知道的目前改進unittest框架的知識是需要class name的 這個我們好像也沒辦法操作
有這麽兩個疑問之後那麽我們可以換一個思考方式,既然參數話目前掌握的知識我們只能夠通過上面的參數話去操作,那麽我們如何去更改自己的代碼,然後又不要我們一個一個case的添加?
其實通過上面的代碼大家就已經發現了一個不一樣的地方,我們這個不需要每個方法每個方法去添加,只需要有個class name 就行,那麽我們這樣能夠把所有的case都運用到這個裏面來嗎?答案是肯定的。
我們只需要通過一個簡單的轉換就可以了。
仔細看上面的代碼我們知道,參數話這個代碼肯定是公共的,那我們就把這個抽出來作為一個公共的類:
#-*- coding: utf-8 -*- #author: mushishi #Date:2018年8月26日 import unittest class ParametrizedTestCase(unittest.TestCase): """ 繼承之後,重寫一下,把這個參數傳遞到unittest裏面 """ def __init__(self, methodName=‘runTest‘, param=None): super(ParametrizedTestCase, self).__init__(methodName) self.param = param @staticmethod def parametrize(testcase_klass, param=None): testloader = unittest.TestLoader() testnames = testloader.getTestCaseNames(testcase_klass) suite = unittest.TestSuite() for name in testnames: suite.addTest(testcase_klass(name, param=param)) return suite #這個類我們單獨抽離出來,我們就是用來把這個作為參數化的集中地
看到這裏明白了麽?其實我們只是需要把這個抽離出來,然後我們的case就變成了這樣:
第一個case類:
#-*- coding: utf-8 -*- #author: mushishi #Date:2018年8月26日 from case.ParametrizedTestCase import ParametrizedTestCase class Test01(ParametrizedTestCase): def test_01_case(self): print("這個是test01case裏面的參數",self.param) def test_02_case(self): print("這個是test01case裏面的參數",self.param)
第二個case類:
#-*- coding: utf-8 -*- #author: mushishi #Date:2018年8月26日 from case.ParametrizedTestCase import ParametrizedTestCase import unittest from case.pounittest_one import Test01 class TestOne(ParametrizedTestCase): def test_first(self): print (‘param =‘, self.param) self.assertEqual(1, 1) def test_two(self): print (‘param =‘, self.param) self.assertEqual(2, 2) if __name__ == ‘__main__‘: suite = unittest.TestSuite() suite.addTest(ParametrizedTestCase.parametrize(TestOne, param=1)) suite.addTest(ParametrizedTestCase.parametrize(TestOne, param=2)) suite.addTest(ParametrizedTestCase.parametrize(Test01,param=3)) unittest.TextTestRunner(verbosity=2).run(suite)
這裏我引入了兩個case類,但是只是添加了這樣的方法,是不是解決了呢?其實這樣的方法網上很多,但是很多都需要思考怎麽做。或者換一個思維。
Appium python unittest pageobject如何實現加載多個case