很多时候,你会自动化,录制并不能说明什么,录制只是为了提高效率,关键是要搭建框架。会框架就可能成为架构师,将框架搭建起来后就可以给其他组员分配任务了。大家按照一定的规则,将自动化规模扩大,业务覆盖全,这样就可以代替手工测试了。 前面讲了如何录制,讲了一个最简单的框架。那我们现在动手搭建一个简单的自动化测试框架。 这里先介绍一下框架整体的功能,然后每个模块大概讲讲。 当然我搭建的框架不一定是很完美的。
这里的代码还是上回用uiautomiator2录制的android的自动化脚本,在真机上运行很流畅。现在将其改造一下,上得了台面。 首先是建立一个global文件,主要是全局的一些参数,一些方法。其他地方可以公用的。 然后建了一个actions文件夹,其实就是业务部分,有些人喜欢叫bussiness,或者page,按照页面分也可以,里面可以定义一些业务actions. 例如此处的登录:
from globals import d,activity
def memberlogin(username, password):
d(resourceId="com.ef.core.engage.smartenglish:id/debug_login").click()
d.xpath(
'//android.widget.RelativeLayout/android.webkit.WebView[1]/android.webkit.WebView[1]/android.view.View[1]/android.view.View[1]/android.widget.EditText[1]').click()
d.send_keys(username, clear=True)
d.xpath(
'//android.widget.RelativeLayout/android.webkit.WebView[1]/android.webkit.WebView[1]/android.view.View[1]/android.view.View[2]/android.widget.EditText[1]').click()
d.xpath(
'//android.widget.RelativeLayout/android.webkit.WebView[1]/android.webkit.WebView[1]/android.view.View[1]/android.view.View[2]/android.widget.EditText[1]').click()
d.send_keys(password, clear=True)
d(text="Engage Submit").click()
d.wait_activity(activity)
d.xpath(
'//*[@resource-id="com.ef.core.engage.smartenglish:id/main_tab_id_home"]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]').wait()
def traillogin():
d(text="跳过").wait()
d(text="跳过").click(10)
d(text="你的名字?").wait()
当然业务里面元素加一些逻辑来提高其健壮性,比如wait(), wait_timeout,wait_activity,exists,assert s(name=u'听歌识曲', visible=True).wait() 如果不放心,还可以加写time_out,很多行为都有默认的time_out时间,一般是10秒。 这样即使网络不好,你的case也不那么容易失败。 然后建立一个case文件夹,定义case类,就可以写case了
class TestLogin(unittest.TestCase):
@classmethod
def setUpClass(cls):
start_app()
@classmethod
def tearDownClass(cls):
pass
#clear_app()
def setUp(self):
print("prepare accounts\n")
self.username = "st12947"
self.password = "1"
start_app()
def tearDown(self):
print("do something after test : clean up.\n")
log_out()
# clear_app()
def test_member_login(self):
memberlogin(self.username, self.password)
assert (d.xpath(
'//*[@resource-id="com.ef.core.engage.smartenglish:id/main_tab_id_home"]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]').exists)
def test_trail_user_login(self):
traillogin()
assert (d.xpath('//android.widget.ScrollView/android.view.View[1]/android.widget.ImageView[2]').exists)
case里面可以加一些log, 方便失败了调试。case的名字有讲究,只好是看名知意,这样方便维护。还可以加一些comments里面。
后面就是建立运行文件夹和文件了runcase。
import unittest
from cases.test_login import TestLogin
from HTMLTestRunner import HTMLTestRunner
import os
from globals import result_path
if __name__ == '__main__':
suite = unittest.TestSuite()
# 使用这种方法可以对测试用例排序
# tests = [TestMathFunc("test_add"), TestMathFunc("test_minus"), TestMathFunc("test_divide")]
# suite.addTests(tests)
# 使用TestLoader的方法传入TestCase
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestLogin))
# 在同目录下生成txt格式的测试报告
# with open('UnittestTextReport.txt', 'a') as f:
# runner = unittest.TextTestRunner(stream=f, verbosity=2)
# runner.run(suite)
with open(result_path+'/result/HTMLReport.html', 'wb') as f:
runner = HTMLTestRunner(stream=f,
title=u'测试报告',
description=u'测试用例的执行情况',
verbosity=2
)
runner.run(suite)
建一个result文件夹,log和结果都可以在这个文件夹里面。 报告大概是这样的:
你可能要问,我用的啥报告模板,这里告诉你,就是用的最简单的 HTMLTestRunner https://www.cnblogs.com/pandaly/p/13212376.html 文件直接从这里copy的,保存为HTMLTestRunner.py,扔到site-pakages那里去了。 如果你想装13,可以去弄个英文的,或者自己动手改改代码。 当然还需要建一个data文件夹来存放数据的。 建一个util文件夹来实现一些功能。 好了,这个框架就算搭建起来了。麻雀虽小,五脏俱全。剩下的工作,就是将内容填充起来了,然后跑起来了。 如果有条件,可以CICD起来了。 对了,我个人不太注重命名规范,喜欢火速将任务弄起来,如果要搭框架的话,这块还是得多注意。不然大家风格千奇百怪,想想都脑壳疼。