今天刚提交了我的新作《带着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 pymysql
import re
import hashlib
from globals import Config
class 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 requests
import unittest
import hashlib
from Util import ClassDB
from Util import CSRF
from Util import HASH
class 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("<title>登录页面</title>",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("<title>登录页面</title>",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("<title>登录页面</title>",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 requests
import unittest
import hashlib
from Util import ClassDB
from Util import CSRF
from Util import HASH
from parameterized import parameterized
from globals import Config
MESSAGES={
"LOGIN_PAGE":"<title>登录页面</title>",
"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.py
import pytest
from 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 pytest
from playwright.sync_api import Page
from Util import ClassDB
import time
from globals import Config
MESSAGES={
"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的风格。