ここで使用する Unittest は Python の単体テスト フレームワークで、その公式 Web サイトは 25.3.unittest - Unit testing Framework - Python 2.7.18 ドキュメントで、包括的な情報を入手できます。
ユースケースを書くことが増えてくると、後のメンテナンスを容易にするためにユースケース作成の仕様や構成を考慮する必要があり、unittest はそのようなツールです。ここでは例を使用して、unittest スクリプトの使用がどのようなものかを示します。
1 # -*- coding: utf-8 -*-
2 from selenium import webdriver
3 from selenium.webdriver.common.by import By
4 from selenium.webdriver.common.keys import Keys
5 from selenium.webdriver.support.ui import Select
6 from selenium.common.exceptions import NoSuchElementException
7 from selenium.common.exceptions import NoAlertPresentException
8 #导入unittest包
9 import unittest, time, re
10
11 #SearchTest类继承自unittest.TestCase,表明这是一个测试案例
12 class SearchTest(unittest.TestCase):
13 #setUp用于初始化工作
14 def setUp(self):
15 self.driver = webdriver.Firefox()
16 self.driver.implicitly_wait(30)
17 self.base_url = "https://www.baidu.com/"
18 self.verificationErrors = []
19 self.accept_next_alert = True
20
21 #以test开头的是我们的测试脚本
22 def test_search(self):
23 driver = self.driver
24 driver.get(self.base_url + "/")
25 driver.find_element_by_id("kw").click()
26 driver.find_element_by_id("kw").clear()
27 driver.find_element_by_id("kw").send_keys("selenium2")
28 driver.find_element_by_id("su").click()
29
30 def is_element_present(self, how, what):
31 try: self.driver.find_element(by=how, value=what)
32 except NoSuchElementException as e: return False
33 return True
34
35 def is_alert_present(self):
36 try: self.driver.switch_to_alert()
37 except NoAlertPresentException as e: return False
38 return True
39
40 def close_alert_and_get_its_text(self):
41 try:
42 alert = self.driver.switch_to_alert()
43 alert_text = alert.text
44 if self.accept_next_alert:
45 alert.accept()
46 else:
47 alert.dismiss()
48 return alert_text
49 finally: self.accept_next_alert = True
50
51 #在每个测试方法后执行,完成清理工作
52 def tearDown(self):
53 self.driver.quit()
54 self.assertEqual([], self.verificationErrors)
55
56 #整个测试过程集中在unittest的main()模块中,其默认执行以test开头的方法
57 if __name__ == "__main__":
58 unittest.main()
これにより、unittest について直感的に理解できると思います。Unittest.main(): 単体テスト モジュールを直接実行できるテスト スクリプトに変換するために使用します。main() メソッドは、TestLoader クラスを使用して、モジュールに含まれる「test」で始まるすべてのテスト メソッドを検索します。自動的に実装されます。実行メソッドのデフォルトの順序は次のとおりです: ASCII コードの順序に従ってテスト ケースをロードします。数字と文字の順序は 0 ~ 9、AZ、az です。したがって、A で始まるテスト ケース メソッドが最初に実行され、a で始まるテスト ケース メソッドが後で実行されます。
Unittest の
TestCase の概念
は、Testcase インスタンスです。テスト ケースは、setUp の初期化、run の実行、テスト後のtearDown の復元を含む、完全なテスト プロセスです。unittest.TestCase クラス。すべてのテスト ケース クラスによって継承される基本クラス。このクラスは、比較をチェックするための多くのアサート メソッドを提供します。そのうちのいくつかは次のとおりです。
ほとんどのメソッドは名前を見れば理解できるため、使用の敷居は非常に低いです。
TestSuite では、
関数をテストするために複数のテスト ケースが必要になることが多く、複数のテスト ケースを同時に実行することができます。これが TestSuite の概念です。addTest() メソッドは、テスト ケースをテスト スイートに追加するためによく使用されます。
TextTestRunner は
テスト ケースの実行に使用され、run(test) は TestSuite/TestCase の実行に使用されます。テストの結果は TextTestResult インスタンスに保存されます。
TestFixture テスト
の準備前に実行する作業とテストの実行後に実行する作業 (setUp() と TearDown() を含む)。これは、TestCase の setUp と TearDown をオーバーライドすることで実現されます。
これらの主な概念を理解した上で、上記のスクリプトの Unittest.main() の最後の行を次のコードに変更できます。
1 #テスト スイートの構築
2 suite =unittest.TestSuite()
3 suite.addTest(SearchTest("test_search"))
4 #テストの実行
5 Runner = Unittest.TextTestRunner()
6 Runner.run(suite)
は実行後に検出され、実行前に使用されましたUnittest.main() の結果は同じです。
ユースケースの構成
ここでは、スクリプト内に test_case1、test_case2... などの複数の TestCase があると仮定します。その場合、それらの実行順序をどのように制御すればよいでしょうか。
テストケース計画を実行する 1.
直接使用する
Unittest.main()
が実行され、test で始まるすべてのテスト ケース メソッドが検索され、複数のテスト ケースが ASCII 順に実行されます。
テスト ケースを実行するためのオプション 2:
最初にテスト スイートをインスタンス化し、ユース ケースをロードしてから、TextTestRunner を使用してユース ケースを実行します。
1 suite=unittest.TestSuite()
2 suite.addTest(Test('test_case2'))
3 suite.addTest(Test('test_case1'))
4 Runner=unittest.TextTestRunner()
5 Runner.run(suite)
実行順序はユースケースの読み込み順序で、例えばここでは2が先に実行され、1が後に実行されます。
実行テスト ケース シナリオ 3
シナリオ 2 では、数百または数千のユース ケースがある場合、それらを 1 つずつ追加するのは非現実的であるため、defaultTestLoader を使用してロードできます。
1 test_dir = './'
2 Discover = Unittest.defaultTestLoader.discover(test_dir, pattern='*test.py')
3 Runner = Unittest.TextTestRunner()
4 Runner.run(discover)
ここでは ./ を使用して現在のdirectory に *test.py ファイルが指定され、その中のユースケースがプラン 1 と同じ順序で実行されます。
ここで指定したディレクトリの下に、パターンに一致する複数の .py ファイルがある場合はどうなるでしょうか? Discover メソッドを呼び出すには、まず test_dir を通じて検索ディレクトリを定義します。ファイル名が定義されたパターンに一致する場合は、for ループを使用してフィルタリングされたすべてのユース ケースを検索し、ループ内のスイートに追加する必要があります。コードは次のとおりです。
1 は、discover の test_suite の場合:
2 は、test_suite の test_case の場合:
3 test_unit.addTests(test_case)
上記のユースケースの整理方法から、実際のテスト スクリプトの開発では、ディレクトリに xx.py ファイルを作成できることがわかります。テスト ケースが安定して実行されたら、テスト スイートへの追加を容易にするために、test_xx.py に変更できます。ファイル名の一致ルールは pattern パラメータで定義できることに注意してください。
マルチレベルのディレクトリ構造でユースケースを実行したい場合はどうすればよいでしょうか? Discover によって読み取られて実行されるようにするには、_ init _.py ファイルをディレクトリに追加する必要があります。
例
以下は、unittest によって構成されたユース ケース構造の簡単な紹介です。まず、D:\Test_Project ディレクトリを作成し、その下に test_case と test_report を配置して、それぞれユース ケースとレポートを保存します。
テスト ケースを作成します。test_case
の下にテスト ケースを作成します。以下は、Baidu でキーワードを検索し、[設定] をクリックする簡単なデモンストレーションです。
1 文件名为:test_baidu.py
2
3 # -*- coding: utf-8 -*-
4 from selenium import webdriver
5 import unittest, time, re
6
7 class MyTest(unittest.TestCase):
8
9 def setUp(self):
10 self.driver = webdriver.Firefox()
11 self.driver.implicitly_wait(30)
12 self.base_url = "https://www.baidu.com"
13 self.accept_next_alert = True
14
15 def test_02baidu_search(self):
16 u''' 测试百度搜索'''
17 driver = self.driver
18 driver.get(self.base_url + "/")
19 driver.find_element_by_id("kw").click()
20 driver.find_element_by_id("kw").clear()
21 driver.find_element_by_id("kw").send_keys("selenium-test")
22 driver.find_element_by_id("su").click()
23 print("test_baidu__test_02baidu_search")
24
25 def test_01baidu_setting(self):
26 u''' 测试百度首页设置 '''
27 driver = self.driver
28 driver.get(self.base_url + "/")
29 driver.find_element_by_css_selector("div#u1 a.pf").click()
30 driver.find_element_by_class_name("setpref").click()
31 driver.find_element_by_css_selector("div#gxszButton>a.prefpanelgo").click()
32 driver.switch_to_alert().accept()
33 print("test_baidu__test_01baidu_setting")
34
35 def tearDown(self):
36 self.driver.close()
37
38 #从all_test中调用时,可以不要这个
39 if __name__ == "__main__":
40 unittest.main()
テスト ケースを整理した効果を示すために、このファイルを再度コピーし、ファイル名とメソッド名を変更します。
1 文件名为:test_baidu2.py
2
3 # -*- coding: utf-8 -*-
4 from selenium import webdriver
5 import unittest, time, re
6
7 class MyTest(unittest.TestCase):
8 u''' 测试baidu的第二个用例'''
9 def setUp(self):
10 self.driver = webdriver.Firefox()
11 self.driver.implicitly_wait(30)
12 self.base_url = "https://www.baidu.com"
13 self.accept_next_alert = True
14
15 def test_02baidu_search(self):
16 u''' 测试baidu的第二个用例的test_02baidu_search'''
17 driver = self.driver
18 driver.get(self.base_url + "/")
19 driver.find_element_by_id("kw").click()
20 driver.find_element_by_id("kw").clear()
21 driver.find_element_by_id("kw").send_keys("selenium-test")
22 driver.find_element_by_id("su").click()
23 print("test_baidu2__test_02baidu_search")
24
25
26 def test_01baidu_setting(self):
27 u''' 测试baidu的第二个用例的test_01baidu_setting'''
28 driver = self.driver
29 driver.get(self.base_url + "/")
30 driver.find_element_by_css_selector("div#u1 a.pf").click()
31 driver.find_element_by_class_name("setpref").click() driver.find_element_by_css_selector("div#gxszButton>a.prefpanelgo").click()
32 driver.switch_to_alert().accept()
33 print("test_baidu2__test_01baidu_setting")
34
35 def tearDown(self):
36 self.driver.close()
37
38 if __name__ == "__main__":
39 unittest.main()
レポートのスタイルを美しくし、結果を電子メールで送信します。
上では例として 2 つのテスト ケースを作成しましたが、さらに追加することもできます。次に、オープン ソース モジュール HTMLTestRunner を使用してテスト レポートを美しくします。ダウンロードと使用方法については、HTMLTestRunner · PyPI を参照してください。次に、操作の完了後にテストメールが自動的に送信されるようにコードを記述して、簡単に確認できるようにします。次のコードを参照してください。
1 #coding=utf-8
2 import unittest
3 import smtplib
4 from email.mime.text import MIMEText
5 from email.header import Header
6 import time
7 import HTMLTestRunner
8 from email.mime.application import MIMEApplication
9
10 #---发送邮件---
11 def send_email(report_file):
12 sender = "[email protected]"
13 receiver = "[email protected]"
14 smtpserver = "smtp.qq.com"
15 #发送邮箱的账号密码,此处使用的是qq邮箱和第三方登录的授权码
16 username = "[email protected]"
17 password = "gfomcomojtuudijc"
18
19 #定义邮件正文
20 file = open(report_file,"rb")
21 mail_body = file.read()
22 file.close()
23
24 msg = MIMEText(mail_body, _subtype="html", _charset="utf-8")
25 msg["Subject"] = u"自动化测试报告"
26
27 smtp = smtplib.SMTP_SSL("smtp.qq.com")
28 smtp.login(username, password)
29 smtp.sendmail(sender, receiver, msg.as_string())
30 smtp.quit()
31 print("Email has send out !")
32
33 #---将用例添加到测试套件---
34 def creatsuite():
35 testunit=unittest.TestSuite()
36 test_dir = "D:\\Test_Project\\test_case"
37 discover = unittest.defaultTestLoader.discover(test_dir, pattern="test*.py",
38 top_level_dir = None)
39 for test_suite in discover:
40 for test_case in test_suite:
41 testunit.addTest(test_case)
42 print (testunit)
43 return testunit
44
45 if __name__ == "__main__":
46 current_time = time.strftime("%Y-%m-%d-%H-%M")
47 report_dir = "D:\\Test_Project\\test_report\\"
48 report_file = report_dir + current_time + "-Test_Result.html"
49 report_stream = open(report_file, "wb")
50 # runner = unittest.TextTestRunner()
51 # 注意HTMLTestRunner只支持python2
52 runner = HTMLTestRunner.HTMLTestRunner(stream=report_stream,title=u"自动化测试报告", description=u"用例执行情况如下:")
53 runner.run(creatsuite())
54 report_stream.close()
55 send_email(report_file)
上記のコードでは、HTMLTestRunner モジュールを使用して美しいレポートを出力するために、runner = Unittest.TextTestRunner() の代わりに、runner = HTMLTestRunner.HTMLTestRunner() メソッドを使用します。次に、電子メールを送信するメソッドを呼び出します。このファイルを実行すると、次の出力レポートを取得できます。
これを利用すると、ユースケースの実行状況が一目瞭然で、失敗したユースケースの原因を確認してデバッグするのにも便利であると同時に、通知メールも届きます。入力した受信箱。この出力レポートをテキストまたは添付ファイルに追加して、見やすくすることができます
最後に、私の記事を注意深く読んでくださった皆さんに感謝します。互恵性は常に必要です。それほど価値のあるものではありませんが、使用できる場合は、直接受け取ることができます。
書類の入手方法:
このドキュメントは、[ソフトウェア テスト] に参加したい友人にとって、最も包括的で完全な準備倉庫となるはずです。この倉庫は、私が最も困難な旅を乗り越えるのにも同行してくれました。また、あなたのお役に立てれば幸いです。
上記はすべて共有できます。下の小さなカードをクリックして無料で入手してください