大家好,实测系列是含金量非常高且首发的专业论文性质文章,请一定要保存,点赞,分享哦~
chatgpt我不多做介绍了,连我乡下的舅妈都知晓的东西。都说这玩意挺神的,那今天我就亲自来测试一下用gpt来做一次完整的测试流程吧?
流程包括:
分析需求-提炼测试点-写测试用例-生成执行用例的脚本-脚本优化
用来测试的对象呢?一定要真实的,不能那种抽象的虚无缥缈的,比如我看别人让gpt来测试一个水杯,测试一个电梯的。咱直接就来测试网站吧,网站我为了避免引起什么商业纠纷,就用我自己的个人网站来吧。
首先打开我的学员培训网站:
目标:登录功能
需求:用户名,密码,登录按钮。够简单吧?错误后有提示,正确后进入主页。
让我们来看gpt的回答:
不可否认的是,上述回答确实比较乱,没有条理,也确实漏掉了很多测试点,也没有丝毫考虑到我这个登录页面,仿佛回答的只是不知道哪里抄来的套词。于是我重新发问:
经过补充后,内容多了很多,但仍然只能作为自由测试来参考,无法去当做正式工作流程。于是我准备开始推进到写用例过程:
如上图所示,这次的用例确实还算不错,但是距离真正的工作中的用例要求还是相差很多,而且也没有吊我问的边界值,等价类,判定表等,仿佛依然是在拍脑袋随机写用例,而且和我一开始问的我自己的网站也已经仿佛没有任何关联了。但用来作为补充和借鉴是非常好的。
然后就是要去写用例脚本了:
如上图,gpt给出了一个很简单的线性脚本。我们先别管写的是否高级和完整,先来看看这段代码:
selenium自动化脚本的启动和收尾没太大问题;
然后验证了用户名密码输入框是否存在,如果不存在就报错了;
然后用一个错误的用户名密码 登录了一次,验证提示语是否正确;
然后又登录了一次正确的用户名密码,验证是否可以跳转到主页;
然后又验证了一下主页的用户名显示元素是否包含用户名;
最后又点击了一下退出按钮,然后关闭了浏览器。
然后我来点评一下这段代码:
优点:gpt写的代码没有语法问题,直接扫描出来了我的页面中的几个关键元素的定位;代码注释还不错;
缺点:其中的正确用户名、密码、主页、主页用户名展示,主页退出按钮等都是gpt擅自揣测的且没有提前说明,如果给不懂脚本的人来看是会被忽悠住;用例脚本太少了,和上面一大堆的用例完全不是一起来的;用例没有引入什么标准框架,较落后;selenium的定位写法比较落后,最新的版本中这种写法是会报错的。
总结:代码还不能完全落地,仍然需要人来完善,但作为开个头来说还是不错的。类似或低于一个实习生没有经过测试培训的水平吧。
然后,我继续更新问题让其用unittest来重写,以便测试gpt能做到的极限。
继续点评:
优点:使用了uniitest框架;增加了一条测试记住的用例;初始化的代码写在了setup可以保证每条用例的低耦合;
缺点:数量仍然远远不足,且没有使用任何高级的写法,没有考虑时间等待等异常风险
总结:相当于刚毕业的水准。
然后我再次提高询问水准,看看其代码程度:
代码比较多,我就截取一些关键点和新的部分吧:
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
class LoginTestCase(unittest.TestCase):def setUp(self):self.driver = webdriver.Chrome(executable_path='/path/to/chromedriver')self.driver.get('http:/')def tearDown(self):self.driver.quit()def test_invalid_credentials(self):# 测试无效用户名和密码def test_valid_credentials(self):# 测试正确凭据def test_remember_me(self):# 测试是否记住用户名和密码def test_empty_credentials(self):# 测试空用户名和密码def test_long_credentials(self):# 测试过长的用户名和密码def test_lockout_after_failed_attempts(self):# 测试多次失败登录后账户锁定invalid_username = 'testuser'invalid_password = 'wrongpass'username_input, password_input, submit_button = self._get_login_elements()for _ in range(3):...# 检查账户是否被锁定error_msg = self.driver.find_element_by_css_selector('.alert-danger').textself.assertIn('您的账户已被锁定', error_msg)def _get_login_elements(self):# 获取登录表单元素username_input = self.driver.find_element_by_name('username')password_input = self.driver.find_element_by_name('password')remember_me_checkbox = self.driver.find_element_by_id('remember-me')submit_button = self.driver.find_element_by_css_selector('button[type="submit"]')return username_input, password_input, remember_me_checkbox, submit_button
if __name__ == '__main__':unittest.main()
继续点评:
优点:用例条数增多,如果继续追问下去,应该还可以增加;有了初级page-object模式的影子,元素定位独立出来了;
缺点:代码冗余,没有充分利用好用例规程和并发线程,浪费了很多执行时间。仍然没有考虑到一些网络延迟,卡顿等异常风险的处理。尚无数据驱动和关键字驱动概念。
总结:已经可以相当于工作一年左右的工程师水准了。当然代码仍然运行起来很多问题。需要大量人工矫正,不过和之前相比,人要做的事情已经少了不少。
然后我们继续升级提问文案,让其并发一下:
点评:
优点:上述代码中,使用了thread库进行多线程并发;巧妙的初步运用了数据驱动的概念,不但用户名密码是不同的,连每次的提示语和url都进行了断言;初步运用了关键字驱动,来让每个线程自动判断自身的断言目的。而po模式的影子仍然存在;
缺点:多线程的运用没有进行系统的封装,存在较大风险和局限;用例的内容结构比较单一,之前复杂的如测试浏览器记住用户密码等无法参与到这个并发中;线程是按照用例作为基本单位,对需要前后文关联的多用例是无法实现的,(所以需要在线程和用例之间制作新的中间层作为单位比较好);数据分离仍然没有实现。
结论:这种脚本一般来说,市场上的自动化测试人员有的刚毕业就可以写出来,大多是需要3-5年才可以流畅写出来的。还有很多写不到这种水平。
继续优化提问,看看结果:(代码仍然简化,只留下了关键行)
class LoginPage:def __init__(self, driver):self.driver = driverdef load(self):self.driver.get('http:/t/')def login(self, username, password, remember_me):# 输入用户名和密码username_input, password_input, remember_me_checkbox, submit_button = self._get_login_elements()...# 点击“登录”按钮def get_error_message(self):return error_msgdef get_user_info(self):return user_infodef _get_login_elements(self):# 获取登录表单元素return username_input, password_input, remember_me_checkbox, submit_buttonclass LoginTest(unittest.TestCase):def setUp(self):self.driver = webdriver.Chrome(executable_path='/path/to/chromedriver')self.login_page = LoginPage(self.driver)def tearDown(self):self.driver.quit()def test_valid_login(self):# 测试正确凭据登录test_data = {'username': 'testuser', 'password': 'testpass', 'remember_me': True}self.login_page.load()self.login_page.login(test_data['username'], test_data['password'], test_data['remember_me'])# 验证是否成功跳转到主页并显示用户信息def test_invalid_login(self):# 测试无效凭据登录def test_empty_username(self):# 测试空用户名登录class LoginKeywordTest(unittest.TestCase):def setUp(self):self.driver = webdriver.Chrome(executable_path='/path/to/chromedriver')def tearDown(self):self.driver.quit()def test_valid_login(self):# 测试正确凭据登录test_data = {'username': 'testuser', 'password': 'testpass', 'remember_me': True}self._perform_login(test_data)# 验证是否成功跳转到主页并显示用户信息def test_invalid_login(self):# 测试无效凭据登录test_data = {'username': 'fakeuser', 'password': 'fakepass', 'expected_error': '用户名或密码不正确'}self._perform_login(test_data)# 检查错误消息是否正确显示def test_empty_username(self):# 测试空用户名登录......
点评:
优点:增加了关键字驱动,数据驱动,po模式,并发等高级用法。
缺点:各种高级用法割裂严重,并没有融合到一起去实现,而是单纯的写了好几个独立的类demo。(应该是网上没搜到真正核心的高阶脚本,全是教程水平)
总结:作为一个高级助手存在已经非常合格且优秀了,这可以帮助那些大佬自动化工程师,可以更夸张的效率去实现高水平的脚本。gpt生成的脚本,仍然需要人力去矫正和做最后优化,虽然工作量减少了,但是工作难度却一点没降低,上述的代码让不太懂自动化去优化是很难办到的。
尾语:
chatGPT在目前的测试流程中,可以作为全程的一个辅助存在,但距离真正的人类相比仍然有着难以跨越的鸿沟,而操作gpt的人的水准却一点降不了。所以网传gpt可以替代高级以上工程师还是不现实的,但却可以大幅加快工作效率,恐怕这些让领导知道后以后的排期都会短的可怜,大家摸鱼难了。gpt的答案也是从网上到处进行理解后拼接而成,但网上的代码水准一般都是皮毛和入门级,相比较从未出现在网上的工作核心代码仍然差距不小,和那些专家工程师的水准也不在一个世界。作为借鉴和省力来说很棒,堪比一个超级搜索引擎了,并且作为语言模型,能更好的理解我们的需求和说出人类可理解的话才是gpt的真正作用。
大家不必为此焦虑,但是后续互联网的超超超加速发展,和跟不上的人类意识,很可能会爆发出很多的漏洞和机遇。所以为了避免落伍,大家还是要尽快的提高自己的水平,当然这个尽快是真的可以尽快,你可以忽略一些细节和底层,这些gpt会辅助你开发,更加注重表层应用和交互使用等,学习速度当然可以提升。毕竟想要操控gpt写出多牛x的代码的前提是你到了这个牛x的境界才行,否则你都看不懂,更何谈优化和修改矫正等工作,理论上,你要超过gpt的水准才能进行优化。
对于市场的预测,我觉得,gpt对大佬们如虎添翼,哪怕就是我这个假大佬来说,我平时有很多不错的点子和设计,但是没足够的时间去亲力亲为的实现,大量的代码也在浪费自己的精力,有了gpt,我就可以短时间内输出爆炸。那无数个大佬都这样做的结果是什么?就是高技术的饱和式出现。这意味着什么呢?意味着全体工程师的水平断层更加严重,通俗来说就是技术垄断,让底层工程师没机会去学习和研究。这种情况在历史上屡见不鲜,后续的技术阶层固化后,靠知识改变命运会变得困难重重,那么现在就是最后的机会,冲上去赚更多的工资吧!
最后: 下方这份完整的软件测试视频学习教程已经整理上传完成,朋友们如果需要可以自行免费领取【保证100%免费】
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
软件测试技术交流群社:786229024(里面还有工作内推机会,毕竟我们是关系社会。)
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。