> 技术文档 > 数据驱动开发软件测试脚本

数据驱动开发软件测试脚本

📝 面试求职: 「面试试题小程序」 ,内容涵盖 测试基础、Linux操作系统、MySQL数据库、Web功能测试、接口测试、APPium移动端测试、Python知识、Selenium自动化测试相关、性能测试、性能测试、计算机网络知识、Jmeter、HR面试,命中率杠杠的。(大家刷起来…)

📝 职场经验干货:

软件测试工程师简历上如何编写个人信息(一周8个面试)

软件测试工程师简历上如何编写专业技能(一周8个面试)

软件测试工程师简历上如何编写项目经验(一周8个面试)

软件测试工程师简历上如何编写个人荣誉(一周8个面试)

软件测试行情分享(这些都不了解就别贸然冲了.)

软件测试面试重点,搞清楚这些轻松拿到年薪30W+

软件测试面试刷题小程序免费使用(永久使用)


今天刚提交了我的新作《带着ChatGPT玩转软件开发》给出版社,在写作期间跟着ChatGPT学到许多新知识。下面分享数据驱动开发软件测试脚本。

一个注册页面,需要填写下面4项:账号、密码、手机和Email。

  • 账号(唯一,支持字母、数字,长度5-20)。

  • 密码(长度5-30,必须包含大小写字母、数字和特殊字符)。

  • 手机号(唯一,符合中国的手机格式)。

  • Email(唯一,符合有效邮箱国际格式)。

1.对API脚本优化

API测试用例如下。

  • TC-001:测试有效的账号(5-20位字母或数字),测试成功。

  • TC-002:测试账号长度不足(少于5位,恰好为4位)显示错误信息\'账号必须是5-20位字母或数字\'。

  • TC-003:测试账号长度超出(超过20位,恰好为21位)显示错误信息\'账号必须是5-20位字母或数字\'。

  • TC-004:测试账号长度正好为5,测试成功,进入成功页面。

  • TC-005:测试账号长度正好为20,测试成功,进入成功页面。

  • TC-006:测试账号有特殊字符,显示错误信息\'账号必须是5-20位字母或数字\'。

  • TC-007:测试密码为空,显示错误信息\'密码应该哈希进行存储\'。

  • TC-008:输入非法的手机号码格式,预期结果:显示错误信息\'手机号格式错误\'。

  • TC-009:输入手机号码为空,预期结果:显示错误信息\'手机号格式错误\'。

  • TC-010:输入非法的邮箱格式,预期结果:显示错误信息\'邮箱格式错误\'。

  • TC-011:输入邮箱为空,预期结果:显示错误信息\'邮箱格式错误\'。

作为一个用Python requests库写一个API接口程序,一般这样写。

公共类Util.py

# -*- coding: utf-8 -*-import pymysqlimport reimport hashlibfrom globals import Configclass ClassDB: def initDB(self): host = \'localhost\' user = \'root\' password = \'123456\' database = \'ebusiness\' return pymysql.connect(host=host, user=user, password=password, database=database, charset=\'utf8\') def execute_query(self, query, params=None): connection = self.initDB() try: with connection.cursor() as cursor: cursor.execute(query, params) connection.commit() return cursor.fetchall() finally: connection.close() def init_db(self): self.execute_query(\"DELETE FROM code\") self.execute_query(\"DELETE FROM password\") self.execute_query(\"DELETE FROM user\") #用于测试之前插入数据(如setup测试场景) #默认数据 #username=Config.VALID_USERNAME #password=Config.VALID_PASSWORD def init_login(self, username, password): username = username or Config.VALID_USERNAME password = HASH.hash_password(password or Config.VALID_PASSWORD) self.execute_query(\"INSERT INTO user (username, password, phone, email) VALUES (%s, %s, %s, %s)\", (username, password, Config.CONTRACT_PHONE, Config.CONTRACT_EMAIL)) # 关闭数据库连接 def closedb(self,connection): try: connection.close() except MySQLError as e: print(f\"数据库关闭失败: {e}\")class CSRF: def get_csrf(html): pattern = r\'input[^>]+value=\"([^\"]+)\"\' # 使用 re.search 查找匹配 match = re.search(pattern, html) # 提取并打印 value 值 if match: csrftoken_value = match.group(1) return csrftoken_value else: return \"未找到 csrftoken\"class HASH: #对字符串仅更新SHA256散列 def hash_password(password): \"\"\"对密码进行SHA256散列\"\"\" return hashlib.sha256(password.encode(\'utf-8\')).hexdigest()

测试文件Test_Register_1.py

# -*- coding: utf-8 -*-import requestsimport unittestimport hashlibfrom Util import ClassDBfrom Util import CSRFfrom Util import HASHclass TestUserRegistrationAPI(unittest.TestCase): #注册接口的URL REGISTER_URL=\"http://127.0.0.1:8080/CharGPTEbusiness/jsp/RegisterPage.jsp\" def setUp(self): self.session = requests.Session() response = self.session.get(self.REGISTER_URL) self.csrf = CSRF.get_csrf(response.text) self.token = {\"csrftoken\": self.csrf} self.db = ClassDB() self.db.init_db() # 确保每个测试开始前数据库是干净的 def tearDown(self): self.db.init_db() def test_valid_username(self): \"\"\"TC-001:测试有效的账号(5-20位字母或数字)\"\"\" data={ \"csrftoken\": self.csrf, \"username\":\"validUser123\", \"password\":HASH.hash_password(\"Valid123!\"), \"phone\":\"13812345678\", \"email\":\"test@example.com\" } response=requests.post(self.REGISTER_URL,data=data,cookies=self.token) self.assertEqual(response.status_code,200) self.assertIn(\"登录页面\",response.text) def test_username_too_short(self): \"\"\"TC-002:测试账号长度不足(少于5位,恰好为4位)\"\"\" data={ \"csrftoken\": self.csrf, \"username\":\"usr2\", \"password\":HASH.hash_password(\"Valid123!\"), \"phone\":\"13812345678\", \"email\":\"test@example.com\" } response=requests.post(self.REGISTER_URL,data=data,cookies=self.token) self.assertEqual(response.status_code,200) self.assertIn(\"账号必须是5-20位字母或数字\",response.text) def test_username_too_long(self): \"\"\"TC-003:测试账号长度超出(超过20位,恰好为21位)\"\"\" data={ \"csrftoken\": self.csrf, \"username\":\"user12345678901234567\", \"password\":HASH.hash_password(\"Valid123!\"), \"phone\":\"13812345678\", \"email\":\"test@example.com\" } response=requests.post(self.REGISTER_URL,data=data,cookies=self.token) self.assertEqual(response.status_code,200) self.assertIn(\"账号必须是5-20位字母或数字\",response.text) def test_valid_username_length_5(self): \"\"\"TC-004:测试账号长度正好为5\"\"\" data={ \"csrftoken\": self.csrf, \"username\":\"User5\", \"password\":HASH.hash_password(\"Valid123!\"), \"phone\":\"13812345678\", \"email\":\"test@example.com\" } response=requests.post(self.REGISTER_URL,data=data,cookies=self.token) self.assertEqual(response.status_code,200) self.assertIn(\"登录页面\",response.text) def test_valid_username_length_20(self): \"\"\"TC-005:测试账号长度正好为20\"\"\" data={ \"csrftoken\": self.csrf, \"username\":\"User5User5User5User5\", \"password\":HASH.hash_password(\"Valid123!\"), \"phone\":\"13812345678\", \"email\":\"test@example.com\" } response=requests.post(self.REGISTER_URL,data=data,cookies=self.token) self.assertEqual(response.status_code,200) self.assertIn(\"登录页面\",response.text) def test_usename_include_spec_char(self): \"\"\"TC-006:测试账号有特殊字符,显示错误信息\'账号必须是5-20位字母或数字\'\'\"\"\" data={ \"csrftoken\": self.csrf, \"username\":\"valid@User\", \"password\":HASH.hash_password(\"Valid123!\"), \"phone\":\"12345\", \"email\":\"invalid@example.com\" } response=requests.post(self.REGISTER_URL,data=data,cookies=self.token) self.assertEqual(response.status_code,200) self.assertIn(\"账号必须是5-20位字母或数字\",response.text) def test_password_is_null(self): \"\"\"TC-007: 测试密码为空,显示错误信息\'密码应该哈希进行存储\'\"\"\" data={ \"csrftoken\": self.csrf, \"username\":\"validUser123\", \"password\":\"\", \"phone\":\"13681732596\", \"email\":\"invalid@example.com\" } response=requests.post(self.REGISTER_URL,data=data,cookies=self.token) self.assertEqual(response.status_code,200) self.assertIn(\"密码应该哈希进行存储\",response.text) def test_invalid_phone(self): \"\"\"TC-008:输入非法的手机号码格式,预期结果:显示错误信息\'手机号格式错误\'。\"\"\" data={ \"csrftoken\": self.csrf, \"username\":\"validUser123\", \"password\":HASH.hash_password(\"\"), \"phone\":\"23111223344\", \"email\":\"test@example.com\" } response=requests.post(self.REGISTER_URL,data=data,cookies=self.token) self.assertEqual(response.status_code,200) self.assertIn(\"手机号必须符合中国手机号码格式\",response.text) def test_phone_is_null(self): \"\"\"TC-009:输入手机号码为空,预期结果:显示错误信息\'手机号格式错误\'。\'\"\"\" data={ \"csrftoken\": self.csrf, \"username\":\"validUser123\", \"password\":HASH.hash_password(\"Valid123!\"), \"phone\":\"\", \"email\":\"test@example.com\" } response=requests.post(self.REGISTER_URL,data=data,cookies=self.token) self.assertEqual(response.status_code,200) self.assertIn(\"手机号必须符合中国手机号码格式\",response.text) def test_invalid_mail(self): \"\"\"TC-010:输入非法的邮箱格式,预期结果:显示错误信息\'邮箱格式错误\'。\'\"\"\" data={ \"csrftoken\": self.csrf, \"username\":\"validUser123\", \"password\":HASH.hash_password(\"Valid123!\"), \"phone\":\"13645678899\", \"email\":\"test@example\" } response=requests.post(self.REGISTER_URL,data=data,cookies=self.token) self.assertEqual(response.status_code,200) self.assertIn(\"Email格式不正确\",response.text) def test_mail_is_null(self): \"\"\"TC-011:输入邮箱为空,预期结果:显示错误信息\'邮箱格式错误\'。\'\"\"\" data={ \"csrftoken\": self.csrf, \"username\":\"validUser123\", \"password\":HASH.hash_password(\"Valid123!\"), \"phone\":\"13645678899\", \"email\":\"test@example\" } response=requests.post(self.REGISTER_URL,data=data,cookies=self.token) self.assertEqual(response.status_code,200) self.assertIn(\"Email格式不正确\",response.text)if __name__==\"__main__\": unittest.main()

我们建立globals.py,定义公共数据

class Config: REGISTER_URL=\"http://127.0.0.1:8080/CharGPTEbusiness/jsp/RegisterPage.jsp\" VALID_USERNAME=\"validUser123\" VALID_PASSWORD=\"Valid123!\" VALID_PHONE=\"13812345677\" VALID_EMAIL=\"valid@example.com\" SHORT_USERNAME=\"usr2\" LONG_USERNAME=\"user12345678901234567\" SHORT_PLUS1_USERNAME=\"usr12\" LONG_REDUCE1_USERNAME=\"user1234567890123456\" WITCH_SPEC_CHAR_USERNAME=\"user@123\" ZERO_SIZE_STRING=\"\" INVALID_PHONE=\"23144556677\" INVALID_EMAIL=\"a@b\"

定义测试文件Test_Register_2.py。

# -*- coding: utf-8 -*-import requestsimport unittestimport hashlibfrom Util import ClassDBfrom Util import CSRFfrom Util import HASHfrom parameterized import parameterizedfrom globals import ConfigMESSAGES={ \"LOGIN_PAGE\":\"登录页面\", \"INVALID_USERNAME\":\"账号必须是5-20位字母或数字\", \"INVALID_PHONE\":\"手机号必须符合中国手机号码格式\", \"INVALID_EMAIL\":\"Email格式不正确\", \"NO_HASH\":\"密码应该哈希进行存储\",}class TestUserRegistrationAPI(unittest.TestCase): def setUp(self): self.session = requests.Session() response = self.session.get(Config.REGISTER_URL) self.csrf = CSRF.get_csrf(response.text) self.token = {\"csrftoken\": self.csrf} self.db = ClassDB() self.db.init_db() # 确保每个测试开始前数据库是干净的 def tearDown(self): self.db.init_db() def _prepare_registration_data(self, username, password, phone, email, expected_message): if expected_message!=\"密码应该哈希进行存储\": password = HASH.hash_password(password) return { \"csrftoken\": self.csrf, \"username\": username, \"password\": password, \"phone\": phone,  \"email\": email, } @parameterized.expand([ (Config.VALID_USERNAME,Config.VALID_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"LOGIN_PAGE\"]), (Config.SHORT_USERNAME,Config.VALID_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_USERNAME\"]), (Config.LONG_USERNAME,Config.VALID_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_USERNAME\"]), (Config.SHORT_PLUS1_USERNAME,Config.VALID_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"LOGIN_PAGE\"]), (Config.LONG_REDUCE1_USERNAME,Config.VALID_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"LOGIN_PAGE\"]), (Config.WITCH_SPEC_CHAR_USERNAME,Config.VALID_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_USERNAME\"]), (Config.VALID_USERNAME,Config.ZERO_SIZE_STRING,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"NO_HASH\"]), (Config.VALID_USERNAME,Config.VALID_PASSWORD,Config.INVALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_PHONE\"]), (Config.VALID_USERNAME,Config.VALID_PASSWORD,Config.ZERO_SIZE_STRING,Config.VALID_EMAIL,MESSAGES[\"INVALID_PHONE\"]), (Config.VALID_USERNAME,Config.VALID_PASSWORD,Config.VALID_PHONE,Config.INVALID_EMAIL,MESSAGES[\"INVALID_EMAIL\"]), (Config.VALID_USERNAME,Config.VALID_PASSWORD,Config.VALID_PHONE,Config.ZERO_SIZE_STRING,MESSAGES[\"INVALID_EMAIL\"]), ]) def test_register(self,username,password,phone,email,expected_message): \"\"\"TC-001:测试有效的账号(5-20位字母或数字),测试成功。\"\"\" \"\"\"TC-002:测试账号长度不足(少于5位,恰好为4位)显示错误信息\'账号必须是5-20位字母或数字\'。\"\"\" \"\"\"TC-003:测试账号长度超出(超过20位,恰好为21位)显示错误信息\'账号必须是5-20位字母或数字\'。\"\"\" \"\"\"TC-004:测试账号长度正好为5,测试成功,进入成功页面。\"\"\" \"\"\"TC-005:测试账号长度正好为20,测试成功,进入成功页面。\"\"\" \"\"\"TC-006:测试账号有特殊字符,显示错误信息\'账号必须是5-20位字母或数字\'。\"\"\" \"\"\"TC-007:测试密码为空,显示错误信息\'密码应该哈希进行存储\'。\"\"\" \"\"\"TC-008:输入非法的手机号码格式,预期结果:显示错误信息\'手机号格式错误\'。\"\"\" \"\"\"TC-009:输入手机号码为空,预期结果:显示错误信息\'手机号格式错误\'。\"\"\" \"\"\"TC-010:输入非法的邮箱格式,预期结果:显示错误信息\'邮箱格式错误\'。\"\"\" \"\"\"TC-011:输入邮箱为空,预期结果:显示错误信息\'邮箱格式错误\'。\"\"\" \"\"\"TC-012:没有CSRF Token,预期结果:返回注册页面。\"\"\" data=self._prepare_registration_data(username,password,phone,email, expected_message) response=self.session.post(Config.REGISTER_URL, data=data, cookies=self.token) response.raise_for_status()#直接抛出异常 self.assertEqual(response.status_code, 200) self.assertIn(expected_message, response.text)if __name__==\"__main__\": unittest.main()

由于post数据均为

{ \"csrftoken\":self.csrf, \"username\":username, \"password\":password, \"phone\":phone, \"email\":email,}

可以独立出一个函数。

def _prepare_registration_data(self, username, password, phone, email, expected_message): if expected_message!=\"密码应该哈希进行存储\": password = HASH.hash_password(password) return { \"csrftoken\":self.csrf, \"username\":username, \"password\":password, \"phone\":phone,  \"email\":email, }

另外在主程序中使用@parameterized.expand用于测试数据参数化。

错误数据封装在字典类型MESSAGES变量中。

2.对GUI脚本优化

GUI测试用例如下。

  • GTC-001-账号有效性测试:输入有效账号(5-20位字母或数字),预期结果,显示:\"注册成功\"。

  • GTC-002-密码长度不足:密码长度少于5位(恰好为4位),预期结果为显示错误信息:\"密码必须是5-30位,包含大小写字母、数字和特殊字符\"。

  • GTC-003-密码长度超出测试:输入超过30位的密码(恰好为31位),预期结果为显示错误信息:\"密码必须是5-30位,包含大小写字母、数字和特殊字符\"。

  • GTC-004-密码确认一致性测试:输入不一致的密码与确认密码,预期结果为显示错误信息:\"密码确认不一致\"。

  • GTC-005-手机号格式错误测试:输入非法手机号码格式,预期结果为显示错误信息:\"手机号格式错误\"。

  • GTC-006-Email格式错误测试:输入非法手机号码格式,预期结果为显示错误信息:\"Email格式错误\"。

  • GTC-007-密码长度为5位:密码长度恰好为5位,预期结果,显示:\"注册成功\"。

  • GTC-008-密码长度为30位:密码长度恰好为30位,预期结果,显示:\"注册成功\"。

  • GTC-009-密码不包含特殊字符:密码不包含特殊字符,预期结果为显示错误信息:\"密码必须是5-30位,包含大小写字母、数字和特殊字符\"。

  • GTC-010-密码不包含小写字符:密码不包含小写字符,预期结果为显示错误信息:\"密码必须是5-30位,包含大小写字母、数字和特殊字符\"。

  • GTC-011-密码不包含大写字符:密码不包含大写字符,预期结果为显示错误信息:\"密码必须是5-30位,包含大小写字母、数字和特殊字符\"。

  • GTC-012-密码不包含数字字符:密码不包含数字字符,预期结果为显示错误信息:\"密码必须是5-30位,包含大小写字母、数字和特殊字符\"。

一般的测试用例如下.

Test_Register_GUI_1.pyimport pytestfrom playwright.sync_api import Page#测试类class TestUserRegistrationAPI: @pytest.fixture(scope=\"module\") def setup(self): with sync_playwright()as p: self.browser=p.chromium.launch(headless=False)#设为 True 可以在后台运行 self.page=self.browser.new_page() self.page.goto(\'http://127.0.0.1:8080/CharGPTEbusiness/jsp/RegisterPage.jsp\')#请替换为你的HTML文件路径 yield self.browser.close() def test_valid_username(self,setup): \'\'\'GTC-001-账号有效性测试\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'validUser123\') page.fill(\'input[name=\"password\"]\',\'ValidPass123!\') page.fill(\'input[name=\"confirmPassword\"]\',\'ValidPass123!\') page.fill(\'input[name=\"phone\"]\',\'13800138000\') page.fill(\'input[name=\"email\"]\',\'test@example.com\') page.click(\'button[type=\"submit\"]\') #检查注册是否成功(这里需要根据实际页面反馈调整) assert page.locator(\'text=注册成功\').is_visible() def test_invaild_password(self,setup): \'\'\'GTC-002-密码长度不足测试(恰好为4位)\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'testUser\') page.fill(\'input[name=\"password\"]\',\'Va@3\') page.fill(\'input[name=\"confirmPassword\"]\',\'Va@3\') page.fill(\'input[name=\"phone\"]\',\'13800138000\') page.fill(\'input[name=\"email\"]\',\'test@example.com\') page.click(\'button[type=\"submit\"]\') #检查错误信息 assert page.locator(\'text=密码必须包含大小写字母、数字和特殊字符,长度在5-30之间\').is_visible() def test_password_length_too_long(self,setup): \'\'\'GTC-003-密码长度超出测试(恰好为31位)\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'testUser\') page.fill(\'input[name=\"password\"]\',\'iLongpassword12@Longpassword12@\') page.fill(\'input[name=\"confirmPassword\"]\',\'iLongpassword12@Longpassword12@\') page.fill(\'input[name=\"phone\"]\',\'13800138000\') page.fill(\'input[name=\"email\"]\',\'test@example.com\') page.click(\'button[type=\"submit\"]\') #检查错误信息 assert page.locator(\'text=密码必须包含大小写字母、数字和特殊字符,长度在5-30之间\').is_visible() def test_password_consistency(self,setup): \'\'\'GTC-004-输入密码与确认密码确保不一致性\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'testUser\') page.fill(\'input[name=\"password\"]\',\'ValidPass123!\') page.fill(\'input[name=\"confirmPassword\"]\',\'validPass123!\')#不一致密码 page.fill(\'input[name=\"phone\"]\',\'13800138000\') page.fill(\'input[name=\"email\"]\',\'test@example.com\') page.click(\'button[type=\"submit\"]\') #检查错误信息 assert page.locator(\'text=密码确认不一致\').is_visible() def test_invalid_phone_format(self,setup): \'\'\'GTC-005-手机号格式错误测试:\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'testUser\') page.fill(\'input[name=\"password\"]\',\'ValidPass123!\') page.fill(\'input[name=\"confirmPassword\"]\',\'ValidPass123!\') page.fill(\'input[name=\"phone\"]\',\'12345\')#非法手机号 page.fill(\'input[name=\"email\"]\',\'test@example.com\') page.click(\'button[type=\"submit\"]\') #检查错误信息 assert page.locator(\'text=请输入有效的中国手机号\').is_visible() def test_invalid_phone_format(self,setup): \'\'\'GTC-006-Emai格式错误测试:\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'testUser\') page.fill(\'input[name=\"password\"]\',\'ValidPass123!\') page.fill(\'input[name=\"confirmPassword\"]\',\'ValidPass123!\') page.fill(\'input[name=\"phone\"]\',\'13455667788\')#非法手机号 page.fill(\'input[name=\"email\"]\',\'test@example\') page.click(\'button[type=\"submit\"]\') #检查错误信息 assert page.locator(\'text=邮箱格式错误\').is_visible() def test_password_length_5(self,setup): \'\'\'GTC-007-密码长度为5位:密码长度恰好为5位:\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'validUser123\') page.fill(\'input[name=\"password\"]\',\'Ab@12\') page.fill(\'input[name=\"confirmPassword\"]\',\'Ab@12\') page.fill(\'input[name=\"phone\"]\',\'13800138000\') page.fill(\'input[name=\"email\"]\',\'test@example.com\') page.click(\'button[type=\"submit\"]\') #检查注册是否成功(这里需要根据实际页面反馈调整) assert page.locator(\'text=注册成功\').is_visible() def password_length_30(self,setup): \'\'\'GTC-008-密码长度为30位:密码长度恰好为30位。\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'validUser123\') page.fill(\'input[name=\"password\"]\',\'Ab@1212345Ab@1212345Ab@1212345Ab@1212345\') page.fill(\'input[name=\"confirmPassword\"]\',\' Ab@1212345Ab@1212345Ab@1212345Ab@1212345\') page.fill(\'input[name=\"phone\"]\',\'13800138000\') page.fill(\'input[name=\"email\"]\',\'test@example.com\') page.click(\'button[type=\"submit\"]\') #检查注册是否成功(这里需要根据实际页面反馈调整) assert page.locator(\'text=注册成功\').is_visible() def test_password_no_include_other_char(self,setup): \'\'\'GTC-009-密码不包含特殊字符:密码不包含特殊字符\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'testUser\') page.fill(\'input[name=\"password\"]\',\'Abc123\') page.fill(\'input[name=\"confirmPassword\"]\',\'Abc123\') page.fill(\'input[name=\"phone\"]\',\'13800138000\') page.fill(\'input[name=\"email\"]\',\'test@example.com\') page.click(\'button[type=\"submit\"]\') #检查错误信息 assert page.locator(\'text=密码必须包含大小写字母、数字和特殊字符,长度在5-30之间\').is_visible() def test_duplicate_no_include_lowercase_char(self,setup): \'\'\'GTC-010-密码不包含小写字符:密码不包含小写字符\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'testUser\') page.fill(\'input[name=\"password\"]\',\'A@@123\') page.fill(\'input[name=\"confirmPassword\"]\',\'A@@123\') page.fill(\'input[name=\"phone\"]\',\'13800138000\') page.fill(\'input[name=\"email\"]\',\'test@example.com\') page.click(\'button[type=\"submit\"]\') #检查错误信息 assert page.locator(\'text=密码必须包含大小写字母、数字和特殊字符,长度在5-30之间\').is_visible() def test_no_include_capital_char(self,setup): \'\'\'GTC-011-密码不包含大写字符:密码不包含大写字符\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'testUser\') page.fill(\'input[name=\"password\"]\',\'a@@123\') page.fill(\'input[name=\"confirmPassword\"]\',\'a@@123\') page.fill(\'input[name=\"phone\"]\',\'13800138000\') page.fill(\'input[name=\"email\"]\',\'test@example.com\') page.click(\'button[type=\"submit\"]\') #检查错误信息 assert page.locator(\'text=密码必须包含大小写字母、数字和特殊字符,长度在5-30之间\').is_visible() def test_no_include_capital_digest(self,setup): \'\'\'GTC-012-密码不包含数字字符:密码不包含数字字符\'\'\' page.goto(REGISTER_URL) page.fill(\'input[name=\"username\"]\',\'testUser\') page.fill(\'input[name=\"password\"]\',\'a@@ABC\') page.fill(\'input[name=\"confirmPassword\"]\',\'a@@ABC\') page.fill(\'input[name=\"phone\"]\',\'13800138000\') page.fill(\'input[name=\"email\"]\',\'test@example.com\') page.click(\'button[type=\"submit\"]\') #检查错误信息 assert page.locator(\'text=密码必须包含大小写字母、数字和特殊字符,长度在5-30之间\').is_visible()if __name__==\"__main__\": pytest.main([\"-sv\", \"Test_Register_GUI_1.py\"])

下面,我们仍对测试数据参数化,在globals.py中加入

LOGIN_URL=http://127.0.0.1:8080/CharGPTEbusiness/jsp/LoginPage.jsp SIMPLE_PASSWORD = \"12345\" FIVE_LENGTH_PASSWORD = \"Ab@12\" THIRTY_LENGTH_PASSWORD=\"Ab@1212345Ab@1212345Ab@1212345Ab@1212345\" NOT_INCLUE_OTHER_CHAR_PASSWORD = \"Abc123\" NOT_INCLUE_LOWERCASE_CHAR_PASSWORD = \"A@@123\" NOT_INCLUE_CAPITAL_CHAR_PASSWORD = \" a@@123\" NOT_INCLUE_DIGEST_PASSWORD= \" a@@ABC\"

测试程序

import pytestfrom playwright.sync_api import Pagefrom Util import ClassDBimport timefrom globals import ConfigMESSAGES={ \"LOGIN_PAGE\":\"登录\", \"INVALID_PASSWORD\": \"密码必须包含大小写字母、数字和特殊字符,长度在5-30之间\", \"INVALID_REPASSWORD\":\"密码确认不一致\", \"INVALID_PHONE\":\"请输入有效的中国手机号\", \"USERNAME_CONFLICT\":\"注册用户的用户名必须唯一\", \"PHONE_CONFLICT\":\"注册用户的手机必须唯一\", \"EMAIL_CONFLICT\":\"注册用户的邮箱必须唯一\",}

Test_Register_GUI_2.py

class TestUserRegistration: @pytest.fixture(autouse=True) def setup_and_teardown(self): self.db = ClassDB() self.db.init_db() yield self.db.init_db() def _fill_registration_form(self, page: Page, username: str, password: str, repassword: str, phone: str, email: str): page.fill(\'input[name=\"username\"]\', username) page.fill(\'input[name=\"password\"]\', password) page.fill(\'input[name=\"confirmPassword\"]\', repassword) page.fill(\'input[name=\"phone\"]\', phone) page.fill(\'input[name=\"email\"]\', email) page.click(\'button[type=\"submit\"]\') @pytest.mark.parametrize(\"username, password, repassword, phone, email, expected_message\", [ (Config.VALID_USERNAME,Config.VALID_PASSWORD,Config.VALID_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"LOGIN_PAGE\"]), #GTC-001-账号有效性测试 (Config.VALID_USERNAME,Config.SHORT_PASSWORD,Config.SHORT_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_PASSWORD\"]), #GTC-002 - 密码长度不足测试 (Config.VALID_USERNAME,Config.LONG_PASSWORD,Config.LONG_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_PASSWORD\"]), #GTC-003 - 密码长度超出测试 (Config.VALID_USERNAME,Config.VALID_PASSWORD,Config.INVALID_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_REPASSWORD\"]), #GTC-004 - 输入密码与确认密码确保不一致性 (Config.VALID_USERNAME,Config.VALID_PASSWORD,Config.VALID_PASSWORD,Config.INVALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_PHONE\"]), #GTC-005 - 手机号格式错误测试 (Config.VALID_USERNAME,Config.FIVE_LENGTH_PASSWORD,Config.FIVE_LENGTH_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"LOGIN_PAGE\"]), #GTC-009-密码长度为5位:密码长度恰好为5位 (Config.VALID_USERNAME,Config.THIRTY_LENGTH_PASSWORD,Config.THIRTY_LENGTH_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"LOGIN_PAGE\"]), #GTC-010-密码长度为30位:密码长度恰好为30位 (Config.VALID_USERNAME,Config.NOT_INCLUE_OTHER_CHAR_PASSWORD,Config.NOT_INCLUE_OTHER_CHAR_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_PASSWORD\"]), #GTC-011-密码不包含特殊字符:密码不包含特殊字符 (Config.VALID_USERNAME,Config.NOT_INCLUE_LOWERCASE_CHAR_PASSWORD,Config.NOT_INCLUE_LOWERCASE_CHAR_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_PASSWORD\"]),#GTC-012-密码不包含小写字符:密码不包含小写字符 (Config.VALID_USERNAME,Config.NOT_INCLUE_CAPITAL_CHAR_PASSWORD,Config.NOT_INCLUE_CAPITAL_CHAR_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_PASSWORD\"]), #GTC-013-密码不包含大写字符:密码不包含大写字符 (Config.VALID_USERNAME,Config.NOT_INCLUE_DIGEST_PASSWORD,Config.NOT_INCLUE_DIGEST_PASSWORD,Config.VALID_PHONE,Config.VALID_EMAIL,MESSAGES[\"INVALID_PASSWORD\"]), #GTC-014-密码不包含数字字符:密码不包含数字字符 (Config.SPACE_USERNAME,Config.SPACE_PASSWORD,Config.SPACE_PASSWORD,Config.SPACE_PHONE,Config.SPACE_EMAIL,MESSAGES[\"LOGIN_PAGE\"]), #GTC-016-账号、密码、手机、邮箱前后都有密码 ]) def test_login(self, page: Page, username, password, repassword, phone, email, expected_message): page.goto(Config.REGISTER_URL) page.reload() self._fill_registration_form(page, username, password, repassword, phone, email) if expected_message == \"登录\": assert page.get_by_role(\"heading\", name=\"登录\") else: assert page.locator(\'text=\' + expected_message).is_visible()if __name__ == \'__main__\': pytest.main([\"-sv\", \"Test_Register_GUI_2.py\"])

这里除了对期望结果封装在变量和使用@pytest.mark.parametrize参数化外,由于对于注册菜单的操作都是一样的,因此将这些操作也分装成一个函数。

 def _fill_registration_form(self, page: Page, username: str, password: str, repassword: str, phone: str, email: str): page.fill(\'input[name=\"username\"]\', username) page.fill(\'input[name=\"password\"]\', password) page.fill(\'input[name=\"confirmPassword\"]\', repassword) page.fill(\'input[name=\"phone\"]\', phone) page.fill(\'input[name=\"email\"]\', email) page.click(\'button[type=\"submit\"]\')

这样就有了POM的风格。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

​​

零食品牌排行榜