首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用ChatGPT生成登录产品代码的测试用例和测试脚本

使用ChatGPT生成登录产品代码的测试用例和测试脚本

作者头像
顾翔
发布2024-12-19 19:48:14
发布2024-12-19 19:48:14
37200
代码可运行
举报
运行总次数:0
代码可运行

10.1生成测试用例

10.1.1 申请生成登录测试用例

产品登录页面如下:

代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html>
<head>
	<link rel="stylesheet" href="../css/index.css">
	<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
	 <script src="https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/core.js"></script>
	<script src="https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/sha256.js"></script>
    <title>登录页面</title>
	<script src="../js/index.js" type="text/javascript"></script>
</head>
<body>

<div class="container">
    <h2>登录</h2>
   <form id="loginForm" name="loginForm" method="POST" action="login.jsp" onsubmit="return validateLoginForm();">
   <input type="hidden" id="csrftoken" name="csrftoken" value="vRB6kNVanUDbT8g5b1bMY3fx6eoHXJhHiStsDc8EyAdTx2BkHrFCIXavHSA2ss6u6eZUMYLvH4pJmxCAGcpWWUguwme7AXy6NkTk">
            <div>
                <label for="username">用户名:</label>
                <input type="text" id="username" name="username" placeholder="输入账号" required>
                <div id="usernameError" class="error"></div>
            </div>
            <div>
                <label for="password">密码:</label>
                <input type="password" id="password" name="password" placeholder="输入密码" required>
                <div id="passwordError" class="error"></div>
            </div>
            <button type="submit">登录</button>
    </form>
	<div id="loginError" class="error">

    </div>
	</div>
</body>
</html>

登录页面界面包括。

l账号:文本框,5-20位大小写英文字符、数字。重复的账户不允许注册

l密码:密码框,必须包括大小写英文字符、数字和特殊字符,5-30位,SHA256散列传输。

l登录成功出现“登录XXXX系统”提示。

l登录失败,出现“用户名或密码错误“。

l避免XSS注入

l避免CSRF注入

l避免SQL注入

l不登录,直接在浏览器地址栏粘贴登录后地址,返回登录页面。

请设计测试用例。

10.1.2 生成登录测试用例回复

以下是针对产品登录页面的测试用例设计,涵盖了功能性、边界情况和安全性等方面的测试:

测试用例设计

1)功能性测试

用例ID

测试内容

输入数据

预期结果

TC-001

验证有效用户名和密码登录

用户名: validUser

登录成功,显示“登录XXXX系统”提示

TC-002

验证无效用户名登录

用户名: invalidUser

显示“用户名或密码错误”

TC-003

验证无效密码登录

用户名: validUser, 密码: wrongPassword

显示“用户名或密码错误”

TC-004

验证空用户名登录

用户名: ""密码: validPassword

显示“用户名或密码错误”

TC-005

验证空密码登录

用户名: validUser密码: ""

显示“用户名或密码错误”

TC-006

验证用户名长度边界

用户名: "a"(1个字符)

显示“用户名长度不符合要求”

TC-007

验证密码长度边界

密码: "123"(3个字符)

显示“密码长度不符合要求”

2)边界情况测试

用例ID

测试内容

输入数据

预期结果

TC-008

验证用户名最大长度

用户名: "validUser123456789012345"

登录成功,显示“登录XXXX系统”提示

TC-009

验证用户名最小长度

用户名: "user"

登录成功,显示“登录XXXX系统”提示

TC-010

验证密码最大长度

密码: "ValidPassword123!"(30个字符)

登录成功,显示“登录XXXX系统”提示

TC-011

验证密码最小长度

密码: "P@ss1"

登录成功,显示“登录XXXX系统”提示

3)安全性测试

用例ID

测试内容

输入数据

预期结果

TC-012

验证XSS注入

用户名: " <> alert('XSS') "

显示“用户名或密码错误”

TC-013

验证CSRF保护

模拟CSRF攻击

登录失败,显示“用户名或密码错误”

TC-014

验证SQL注入

用户名: "admin' --"

显示“用户名或密码错误”

4)重定向测试

用例ID

测试内容

输入数据

预期结果

TC-015

验证未登录用户访问登录后地址

直接访问: "/dashboard"

重定向回登录页面

备注

l测试用例中涉及的“有效用户名”和“有效密码”需要根据系统的实际注册情况进行定义。

l安全性测试用例需要在安全测试环境中进行,以避免对生产环境造成影响。

l测试用例的执行结果应记录实际结果与预期结果的对比,确保功能的正确性和安全性。

10.1.3 更新测试用例

假设存在一个账户,用户名:validUser,密码:ValidPassword123!。

1)功能性测试

用例ID

测试内容

输入数据

预期结果

TC-001

验证有效用户名和密码登录

用户名: validUser密码:ValidPassword123!

登录成功,显示“登录XXXX系统”提示

TC-002

验证无效用户名登录

用户名: invalidUser密码:ValidPassword123!

显示“用户名或密码错误”

TC-003

验证无效密码登录

用户名: validUser, 密码: wrongPassword

显示“用户名或密码错误”

TC-004

验证空用户名登录

用户名: ""密码: validPassword

显示“账号必须是5-20位字母或数字”

TC-005

验证空密码登录

用户名: validUser密码: ""

显示“用户名或密码错误”

TC-006

验证用户名长度边界

用户名: "a"(1个字符)

显示“账号必须是5-20位字母或数字”

TC-007

验证密码长度边界

密码: "123"(3个字符)

显示“密码必须包含大小写字母、数字和特殊字符,长度在5-30之间”

lTC-001、TC-002、TC-003、TC-004、TC-005、TC-005:用API测试用例实现。

lTC-006、TC-007:用GUI测试用例实现。

2)边界情况测试

用例ID

测试内容

输入数据

预期结果

TC-008

验证用户名最大长度

用户名: "validUser12345678900"

登录成功,显示“登录XXXX系统”提示

TC-009

验证用户名最小长度

用户名: "user1"

登录成功,显示“登录XXXX系统”提示

TC-010

验证密码最大长度

密码: "ValidPassword1234567890123456!"(30个字符)

登录成功,显示“登录XXXX系统”提示

TC-011

验证密码最小长度

密码: "P@ss1"

登录成功,显示“登录XXXX系统”提示

所以测试用例均用API测试用例实现。

3)安全性测试

用例ID

测试内容

输入数据

预期结果

TC-012

验证XSS注入

用户名: " <> alert('XSS') "

显示“账号必须是5-20位字母或数字”

TC-013

验证CSRF保护

模拟CSRF攻击

登录失败,显示“ ”

TC-014

验证SQL注入

用户名: "admin' --"

显示“账号必须是5-20位字母或数字”

所以测试用例均用API测试用例实现。

4)重定向测试

用例ID

测试内容

输入数据

预期结果

TC-015

验证未登录用户访问登录后地址

登录,然后登出,直接访问: "/welcome.jsp"

重定向回登录页面

所以测试用例均用GUI测试用例实现。

10.2 生成登录API测试用例

10.2.1 申请登录API测试用例

生成如下的基于Python requests类+unittest框架的API测试用例脚本。

lTC-001,验证有效用户名和密码登录,用户名: validUser,密码:ValidPassword123!,登录成功,显示“登录XXXX系统”提示。

lTC-002,验证无效用户名登录,用户名: invalidUser,密码:ValidPassword123!,显示“用户名或密码错误”。

lTC-003,验证无效密码登录,用户名: validUser, 密码: wrongPassword,显示“用户名或密码错误”。

lTC-004,验证空用户名登录,用户名: "",密码: validPassword ,显示“账号必须是5-20位字母或数字”。

lTC-005,验证空密码登录,用户名: validUser,密码: "",显示“密码应该哈希进行存储”。

lTC-008,验证用户名最大长度,用户名: "validUser123456789012345",登录成功,显示“登录XXXX系统”提示。

lTC-009,验证用户名最小长度,用户名: "user1",登录成功,显示“登录XXXX系统”提示。

lTC-010,验证密码最大长度,密码: "ValidPassword1234567890123456!"(30个字符),登录成功,显示“登录XXXX系统”提示。

lTC-011,验证密码最小长度,密码: "P@ss1",登录成功,显示“登录XXXX系统”提示。

lTC-012,验证XSS注入,用户名: " <> alert('XSS') " ,显示“用户名或密码错误”。

lTC-013,验证CSRF保护,模拟CSRF攻击,登录失败,显示“用户名或密码错误”。

lTC-014,验证SQL注入,用户名: "admin' --" ,显示“用户名或密码错误”。

10.2.2登录API测试用例回复

下面是一个基于Python requests 类和 unittest 框架的API测试用例脚本,涵盖您提供的所有测试用例。请确保在运行此脚本之前,您已安装了 requests 库,并将相应的URL和响应内容替换为您实际使用的API。

代码语言:javascript
代码运行次数:0
运行
复制
import requests
import unittest
 
# 基础URL
BASE_URL = "http://your-api-url.com/login"  # 替换为实际的登录API URL
WELCOME_URL = "http://your-api-url.com/welcome.jsp"  # 替换为实际的受保护页面URL
 
class TestLoginAPI(unittest.TestCase):
 
    def test_valid_login(self):
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "登录XXXX系统")
 
    def test_invalid_username(self):
        response = requests.post(BASE_URL, data={'username': "invalidUser", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "用户名或密码错误")
 
    def test_invalid_password(self):
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': "wrongPassword"})
        self.assertEqual(response.json().get('message'), "用户名或密码错误")
 
    def test_empty_username(self):
        response = requests.post(BASE_URL, data={'username': "", 'password': "validPassword"})
        self.assertEqual(response.json().get('message'), "账号必须是5-20位字母或数字")
 
    def test_empty_password(self):
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': ""})
        self.assertEqual(response.json().get('message'), "密码应该哈希进行存储")
 
    def test_username_max_length(self):
        response = requests.post(BASE_URL, data={'username': "validUser123456789012345", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "登录XXXX系统")
 
    def test_username_min_length(self):
        response = requests.post(BASE_URL, data={'username': "user1", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "登录XXXX系统")
 
    def test_password_max_length(self):
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': "ValidPassword1234567890123456!"})
        self.assertEqual(response.json().get('message'), "登录XXXX系统")
 
    def test_password_min_length(self):
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': "P@ss1"})
        self.assertEqual(response.json().get('message'), "登录XXXX系统")
 
    def test_xss_injection(self):
        response = requests.post(BASE_URL, data={'username': "    <>      alert('XSS')      ", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "用户名或密码错误")
 
    def test_csrf_protection(self):
        # 假设CSRF令牌是必需的,这里我们不提供CSRF令牌
        response = requests.post(BASE_URL, data={'username': "validUser", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "用户名或密码错误")
 
    def test_sql_injection(self):
        response = requests.post(BASE_URL, data={'username': "admin' --", 'password': "ValidPassword123!"})
        self.assertEqual(response.json().get('message'), "用户名或密码错误")
 
if __name__ == "__main__":
    unittest.main()

10.2.3调整登录API测试程序

1)修改Util.py
代码语言:javascript
代码运行次数:0
运行
复制
import pymysql
import re
import hashlib
 
class ClassDB:
    #初始化数据库连接
    def initDB(self):
        host = 'localhost'
        user = 'root'
        password = '123456'
        database = 'ebusiness'
        # 创建数据库连接
        connection = pymysql.connect(host=host, user=user, password=password, database=database)
        return connection
        
    # 关闭数据库连接
    def closedb(self,connection):
        connection.close()
 
    # 清空数据库user表中数据,用于DearDown
    def init_db(self):
        connection = self.initDB()
        try:
            with connection.cursor() as cursor:
                # SQL语句,用于清空user表
                sql = "TRUNCATE TABLE user"    
                # 执行SQL语句
                cursor.execute(sql)   
                # 提交事务
                connection.commit()
        finally:
            self.closedb(connection)
 
    #为登录初始化数据
    def init_login(self):
        connection = self.initDB()
        try:
            with connection.cursor() as cursor:
                password = HASH.hash_password("ValidPassword123!")
                # SQL语句,用于清空user表
                sql = "INSERT INTO user (username, password, phone, email) VALUES (\"validUser\",\""+password+"\", \"13611223344\", \"a@b.com\")"  
                # 执行SQL语句
                cursor.execute(sql)       
                # 提交事务
                connection.commit()
        finally:
            self.closedb(connection)
 
    #建立特定用户名的user数据,密码为默认“ValidPassword123!”
    def login_for_name(self,username):
        connection = self.initDB()
        try:
            with connection.cursor() as cursor:
                password = HASH.hash_password("ValidPassword123!")
                # SQL语句,用于清空user表
                sql = "INSERT INTO user (username, password, phone, email) VALUES (\""+username+"\",\""+password+"\", \"13611223344\", \"a@b.com\")"      
                # 执行SQL语句
                cursor.execute(sql)      
                # 提交事务
                connection.commit()
        finally:
            self.closedb(connection)
 
    #建立特定密码的user数据,用户名为默认“validUser”
    def login_for_password(self,password):
        connection = self.initDB()
        try:
            with connection.cursor() as cursor:
                password = HASH.hash_password(password)
                # SQL语句,用于清空user表
                sql = "INSERT INTO user (username, password, phone, email) VALUES (\"validUser\",\""+password+"\", \"13611223344\", \"a@b.com\")"      
                # 执行SQL语句
                cursor.execute(sql)      
                # 提交事务
                connection.commit()
        finally:
            self.closedb(connection)
        
        
        
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()

2)修改TestEbusiness.py为Test_Register.py

代码语言:javascript
代码运行次数:0
运行
复制
…
from Util import ClassDB
from Util import CSRF
from Util import HASH
 
class TestUserRegistration(unittest.TestCase):
       # 注册接口的URL
       def setUp(self):
              self.REGISTER_URL = "http://127.0.0.1:8080/CharGPTEbusiness/jsp/register.jsp"
              self.session = requests.Session()
              response = self.session.get(self.REGISTER_URL)
              self.csrf = CSRF.get_csrf(response.text)
              self.token={"csrftoken":self.csrf}
              
       def tearDown(self):
              self.db = ClassDB()
              self.db.init_db()
…
3) 修改Test_register_GUI.py
…
from Util import ClassDB
import time
 
REGISTER_URL = 'http://127.0.0.1:8080/CharGPTEbusiness/jsp/register.jsp'
# 测试类
class TestUserRegistration:   
    def teardown_class(self):
           self.db = ClassDB()
           self.db.init_db()
…
4)建立Test_Login.py
import requests
import unittest
from Util import ClassDB
from Util import CSRF
from Util import HASH
 
# 基础URL
BASE_URL = "http://127.0.0.1:8080/CharGPTEbusiness/jsp/login.jsp"  # 替换为实际的登录API URL
WELCOME_URL = "http://127.0.0.1:8080/CharGPTEbusiness/jsp//welcome.jsp"  # 替换为实际的受保护页面URL
 
class TestLoginAPI(unittest.TestCase):
    def setUp(self):
        self.session = requests.Session()
        response = self.session.get(BASE_URL)
        self.csrf = CSRF.get_csrf(response.text)
        self.token={"csrftoken":self.csrf}
        self.db = ClassDB()
        self.db.init_login()
              
    def tearDown(self):
        self.db.init_db()
       
    def test_valid_login(self):
        """TC-001:验证有效用户名和密码登录"""
        self.token['username'] = "validUser"
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser",
           'password': HASH.hash_password("ValidPassword123!")
       },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("系统欢迎您", response.text)
    
def test_invalid_username(self):
        """TC-002:验证无效用户名登录"""
        self.token['username'] = "invalidUser"
        response = requests.post(BASE_URL,
       data={
           'csrftoken':self.csrf,
           'username': "invalidUser",
           'password': HASH.hash_password("ValidPassword123!")
       },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("用户名或密码错误", response.text)
 
    def test_invalid_password(self):
        """TC-003,验证无效密码登录"""
        self.token['username'] = "validUser"
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser",
           'password': HASH.hash_password("wrongPassword")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("用户名或密码错误", response.text)
 
    def test_empty_username(self):
        """TC-004,验证空用户名登录"""
        self.token['username'] = ""
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "",
           'password':HASH. hash_password("validPassword")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("     ", response.text)
 
    def test_empty_password(self):
        """TC-005,验证空密码登录"""
        self.token['username'] = "validUser"
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser",
           'password': HASH.hash_password("")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("用户名或密码错误", response.text)
 
    def test_username_max_length(self):
        """TC-008,验证用户名最大长度"""
        self.token['username'] = "validUser12345678900"
        self.db.login_for_name("validUser12345678900")
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser12345678900",
           'password': HASH.hash_password("ValidPassword123!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("系统欢迎您", response.text)
    
    def test_username_min_length(self):
        """TC-009,验证用户名最小长度"""
        self.token['username'] =  "user1"
        self.db.login_for_name("user1")
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "user1",
           'password':HASH.hash_password("ValidPassword123!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("欢迎", response.text)
        self.assertIn("登录", response.text)
        self.assertIn("系统", response.text)
 
    def test_password_max_length(self):
        """TC-010,验证密码最大长度"""
        self.token['username'] = "validUser"
        self.db.login_for_password("ValidPassword1234567890123456!")
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser",
           'password': HASH.hash_password("ValidPassword1234567890123456!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("系统欢迎您", response.text)
 
    def test_password_min_length(self):
        """TC-011,验证密码最小长度"""
        self.token['username'] = "validUser"
        self.db.login_for_password("P@ss1")
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "validUser",
           'password': HASH.hash_password("P@ss1")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("系统欢迎您", response.text)
 
    def test_xss_injection(self):
        """TC-012,验证XSS注入"""
        self.token['username'] = "    <>      alert('XSS')      "
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
            'username': "    <>      alert('XSS1')      ",
           'password': HASH.hash_password("ValidPassword123!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("账号必须是5-20位字母或数字", response.text)
 
    def test_csrf_protection(self):
        """TC-013,验证CSRF保护"""
       # 假设CSRF令牌是必需的,这里我们不提供CSRF令牌
        self.token['username'] = "validUser"
        response = requests.post(BASE_URL, data={
           'username': "validUser",
           'password': HASH.hash_password("ValidPassword123!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("     ", response.text)
 
    def test_sql_injection(self):
        """TC-014,验证SQL注入"""
        self.token['username'] = "admin' --"
        response = requests.post(BASE_URL, data={
           'csrftoken':self.csrf,
           'username': "admin' --",
           'password': HASH.hash_password("ValidPassword123!")
           },cookies=self.token)
        self.assertEqual(response.status_code, 200)
        self.assertIn("账号必须是5-20位字母或数字", response.text)
 
if __name__ == "__main__":
       unittest.main()
10.3 生成登录GUI测试用例
10.3.1 申请生成登录GUI测试用例
对下面用例书写基于playwright+pytest的测试脚本。

前端代码

代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html>
<head>
	<link rel="stylesheet" href="../css/index.css">
	<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
	 <script src="https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/core.js"></script>
	<script src="https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/sha256.js"></script>
    <title>登录页面</title>
	<script src="../js/index.js" type="text/javascript"></script>
</head>
<body>

<div class="container">
    <h2>登录</h2>
   <form id="loginForm" name="loginForm" method="POST" action="login.jsp" onsubmit="return validateLoginForm();">
   <input type="hidden" id="csrftoken" name="csrftoken" value="yDhOJU4vOCv6qSENtpba8xaURQlQlpGQ9W4hJekAt45dLi9ByMEs2DOzaLwtjeo2P4b1pV0crpDqxQo1F3w23blijWE1OBsj99ke">
            <div>
                <label for="username">用户名:</label>
                <input type="text" id="username" name="username" placeholder="输入账号" required>
                <div id="usernameError" class="error"></div>
            </div>
            <div>
                <label for="password">密码:</label>
                <input type="password" id="password" name="password" placeholder="输入密码" required>
                <div id="passwordError" class="error"></div>
            </div>
            <button type="submit">登录</button>
    </form>
	<div id="loginError" class="error">

    </div>
	</div>
</body>
</html>

对下面用例实现基于GUI的测试用例

lTC-001 验证有效用户名和密码登录,用户名: validUser,登录成功,显示“登录XXXX系统”提示。

lTC-002 验证无效用户名登录,用户名: invalidUser,显示“用户名或密码错误”。

lTC-006 验证用户名长度边界,用户名: "a"(1个字符),显示“账号必须是5-20位字母或数字”。

lTC-007 验证密码长度边界,密码: "123"(3个字符),显示“密码必须包含大小写字母、数字和特殊字符,长度在5-30之间”。

lTC-015 验证未登录用户访问登录后地址,登录,然后登出,直接访问: "/welcome.jsp"重定向回登录页面。

假设存在一个账户,用户名:validUser,密码:ValidPassword123!。

10.3.2 生成登录GUI测试用例回复

下面是基于Playwright和pytest的测试脚本实现,涵盖了您提供的用例。请确保您已经安装了Playwright和pytest,并且已正确配置了测试环境。

首先,您需要在项目目录中创建一个新的Python文件,比如test_login.py,然后将以下代码粘贴到该文件中:

代码语言:javascript
代码运行次数:0
运行
复制
import pytest
from playwright.sync_api import sync_playwright
 
# 测试用例
@pytest.mark.parametrize("username, password, expected_message", [
    ("validUser", "ValidPassword123!", "登录XXXX系统"),  # TC-001
    ("invalidUser", "ValidPassword123!", "用户名或密码错误"),  # TC-002
    ("a", "ValidPassword123!", "账号必须是5-20位字母或数字"),  # TC-006
    ("validUser", "123", "密码必须包含大小写字母、数字和特殊字符,长度在5-30之间"),  # TC-007
])
def test_login(username, password, expected_message):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        page.goto("file://path/to/your/html/file.html")  # 替换为您的HTML文件路径
 
        # 填充用户名和密码
        page.fill("#username", username)
        page.fill("#password", password)
        # 提交表单
        page.click("button[type='submit']")
        
        # 等待页面加载并验证消息
        page.wait_for_selector("#loginError, h2")  # 等待登录错误或成功消息
        
        if expected_message == "登录XXXX系统":
            assert page.locator("h2").inner_text() == expected_message
        else:
            assert page.locator("#loginError").inner_text() == expected_message
        
        browser.close()
 
def test_access_protected_page_after_logout():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        
        # 登录
        page.goto("file://path/to/your/html/file.html")  # 替换为您的HTML文件路径
        page.fill("#username", "validUser")
        page.fill("#password", "ValidPassword123!")
        page.click("button[type='submit']")
        
        # 退出登录
        # 假设有一个退出登录的按钮,您需要根据实际情况进行调整
        page.click("#logoutButton")  # 替换为实际的注销按钮选择器
        
        # 尝试访问受保护的页面
        page.goto("file:///path/to/welcome.jsp")  # 替换为欢迎页面的真实路径
        
        # 验证重定向回登录页面
        assert page.url == "file://path/to/your/html/file.html"  # 替换为登录页面的真实路径
        
        browser.close()

说明

l测试用例: 使用@pytest.mark.parametrize装饰器来定义多个测试用例,涵盖有效和无效的用户名和密码。

l浏览器操作: 使用Playwright的API来启动浏览器、打开页面、填写表单、提交表单并验证结果。

l重定向测试: test_access_protected_page_after_logout函数用于测试未登录用户访问受保护页面的情况。

l路径替换: 请确保将file://path/to/your/html/file.html和file:///path/to/welcome.jsp替换为您本地的实际文件路径。

运行测试

确保您已安装pytest和Playwright。您可以通过以下命令运行测试:

代码语言:javascript
代码运行次数:0
运行
复制
pytest test_login.py

请根据您的具体需求和环境进行调整。

10.3.3调整登录GUI测试程序

代码语言:javascript
代码运行次数:0
运行
复制
import pytest
from playwright.sync_api import Page
from Util import ClassDB
import time
 
LOGIN_URL = 'http://127.0.0.1:8080/CharGPTEbusiness/jsp/login.jsp'
WELCOME_URL ='http://127.0.0.1:8080/CharGPTEbusiness/jsp/welcome.jsp'
# 测试类
class TestUserLogin:
    def setup_class(self):
        self.db = ClassDB()
        self.db.init_login()
 
    def teardown_class(self):
        self.db.init_db()
 
    # 测试用例
    @pytest.mark.parametrize("username, password, expected_message", [
        ("validUser", "ValidPassword123!", "系统欢迎您"),  # TC-001
        ("invalidUser", "ValidPassword123!", "用户名或密码错误"),  # TC-002
        ("a", "ValidPassword123!", "账号必须是5-20位的字母或数字"),  # TC-006
        ("validUser", "123", "密码必须包含大小写字母、数字和特殊字符,长度在5-30之间"),  # TC-007
 
    ])
    def test_login(self,page: Page,username, password, expected_message):
        page.goto(LOGIN_URL)
        page.reload()
 
        # 填充用户名和密码
        page.fill("#username", username)
        page.fill("#password", password)
        page.click("button[type='submit']")
        
        # 等待页面加载并验证消息
        if expected_message == "系统欢迎您":
            page.wait_for_selector("h1")  # 等待成功消息
        else:
            page.wait_for_selector("h2")  # 等待登录错误
        
        if username == "validUser":
            if password != "123":
                assert page.locator("h1").inner_text() == expected_message
            else:
                assert expected_message in page.locator("#passwordError").inner_text()            
        elif username == "invalidUser":
            assert expected_message in page.locator("#loginError").inner_text()
        elif username == "a":
            assert expected_message in page.locator("#usernameError").inner_text()
        else:
                assert 0==1
    def test_access_protected_page_after_logout(self,page: Page):       
        # 登录
        page.goto(LOGIN_URL)
        page.reload()
        page.fill("#username", "validUser")
        page.fill("#password", "ValidPassword123!")
        page.click("button[type='submit']")
        page.wait_for_selector("h1")  # 等待成功消息
        page.click("body > a")  # 替换为实际的注销按钮选择器
        
        # 尝试访问受保护的页面
        page.goto(WELCOME_URL)  # 替换为欢迎页面的真实路径
        # 验证重定向回登录页面
        assert page.url == LOGIN_URL  # 替换为登录页面的真实路径
 
if __name__ == '__main__':
pytest.main(["-sv", "Test_login_GUI.py"])

在这里注意

代码语言:javascript
代码运行次数:0
运行
复制
由于expected_messagez在页面中不同的地方出现,所以调整代码:
if username == "validUser":
      if password != "123":
          assert page.locator("h1").inner_text() == expected_message
      else:
          assert expected_message in page.locator("#passwordError").inner_text()            
elif username == "invalidUser":
      assert expected_message in page.locator("#loginError").inner_text()
elif username == "a":
      assert expected_message in page.locator("#usernameError").inner_text()
else:
      assert 0==1

另外在运行过程中发现:

代码语言:javascript
代码运行次数:0
运行
复制
page.fill("#username", "…")
page.fill("#password", "…")
page.click("button[type='submit']")

经常等待不到,后来通过playwright的录制功能,换了

代码语言:javascript
代码运行次数:0
运行
复制
page.get_by_placeholder("输入账号").fill("validUser")
page.get_by_placeholder("输入密码").fill("ValidPassword123!")
page.get_by_role("button", name="登录").click()

就没有问题了。

注意:在使用ChatGPT辅助开发代码的时候,注意结合其他工具一起使用

另外在运行过程中发现每次密码没有执行散列就传输了,后来发现前端代码

代码语言:javascript
代码运行次数:0
运行
复制
< src="https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/sha256.js">

由于网速很慢,https://cdn.jsdelivr.net/npm/crypto-js@4.1.1/sha256.js无法加载到。把core.js、crypto-js.min.jsh和sha256.js放在项目js目录下。register.jsp和login.js改为:

代码语言:javascript
代码运行次数:0
运行
复制
   < src="../js/crypto-js.min.js">     
    < src="../js/core.js">     
    < src="../js/sha256.js">   

10.3.4调整注册GUI测试程序

根据登录GUI测试程序调整注册GUI测试。使用pytest.mark.parametrizec参数模式。

注意:ChatGPT每次给出的格式不一致,需要根据经验使用最好的程序

代码语言:javascript
代码运行次数:0
运行
复制
import pytest
from playwright.sync_api import Page
from Util import ClassDB
import time
 
REGISTER_URL = 'http://127.0.0.1:8080/CharGPTEbusiness/jsp/register.jsp'
# 测试类
class TestUserRegistration:   
    def teardown(self):
           self.db = ClassDB()
           self.db.init_db()
        
    # 测试用例
    @pytest.mark.parametrize("username, password, repassword, phone, email, expected_message", [
        ("validUser123", "ValidPass123!", "ValidPass123!","13800138000","test@example.com","登录"),  #GTC1-账号有效性测试
       ("testUser", "Aa1@", "Aa1@","13800138000","test@example.com","密码必须包含大小写字母、数字和特殊字符,长度在5-30之间"),  #GTC2 - 密码长度不足测试
       ("testUser", "iLongpassword12@Longpassword12@", "iLongpassword12@Longpassword12@","13800138000","test@example.com","密码必须包含大小写字母、数字和特殊字符,长度在5-30之间"),  #GTC3 - 密码长度超出测试
       ("testUser", "ValidPass123!", "validPass123!","13800138000","test@example.com","密码确认不一致"),  #GTC4 - 输入密码与确认密码确保不一致性
       ("testUser", "ValidPass123!", "ValidPass123!","12345","test@example.com","请输入有效的中国手机号"),  ##GTC5 - 手机号格式错误测试
    ])
    def test_Login(self,page: Page,username, password, repassword, phone, email, expected_message):
        page.goto(REGISTER_URL)
        page.reload()
        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"]')
        # 检查注册是否成功(这里需要根据实际页面反馈调整)
        if expected_message == "登录":
            assert page.get_by_role("heading", name="登录")
        else:
            assert page.locator('text='+expected_message).is_visible()
      
 
    # 测试用例
    @pytest.mark.parametrize("username, password, repassword, phone, email, username_1,phone_1,email_1,expected_message", [
        ("duplicateUser", "ValidPass123!", "ValidPass123!","13800138000","duplicate@example.com","duplicateUser","13800138001","duplicate2@example.com","注册用户的用户名必须唯一"),  #GTC6 – 一个用户重复注册两次。
       ("duplicateUser3", "ValidPass123!", "ValidPass123!","13800138003","duplicate1@example.com","duplicateUser4","13800138003","duplicate1@example.com","注册用户的手机必须唯一"),  #GTC7 – – 不同用户注册,手机号重复
       ("duplicateUser1", "ValidPass123!", "ValidPass123!","13800138004","duplicate3@example.com","duplicateUser4","13800138005","duplicate3@example.com","注册用户的邮箱必须唯一"), #GTC8 – 不同用户注册,邮件重复
    ])
    def test_duplicate(self,page: Page,username, password, repassword, phone, email, username_1,phone_1,email_1,expected_message):
        page.goto(REGISTER_URL)
        page.reload()
        # 第一次注册
        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"]')
        # 检查注册成功
        assert page.get_by_role("heading", name="登录")
        # 第二次注册相同用户
        page.goto(REGISTER_URL)
        page.reload()
        page.fill('input[name="username"]', username_1)
        page.fill('input[name="password"]', password)
        page.fill('input[name="confirmPassword"]', repassword)
        page.fill('input[name="phone"]', phone_1)
        page.fill('input[name="email"]', email_1)
        page.click('button[type="submit"]')
        # 检查错误信息
        print(expected_message)
        assert page.locator('text='+expected_message).is_visible()
 
if __name__ == '__main__':
    pytest.main(["-sv", "Test_register_GUI.py"])

10.4 总结

共有以下测试用例,其中API测试用例12个,分别如下:

lTC-001 验证有效用户名和密码登录

lTC-002 验证无效用户名登录

lTC-003 验证无效密码登录

lTC-004 验证空用户名登录

lTC-005 验证空密码登录

lTC-008 验证用户名最大长度

lTC-009 验证用户名最小长度

lTC-010 验证密码最大长度

lTC-011 验证密码最小长度

lTC-012 验证XSS注入

lTC-013 验证CSRF保护

lTC-014 验证SQL注入

GUI测试用例5个,分别如下:

lTC-001 验证有效用户名和密码登录

lTC-002 验证无效用户名登录

lTC-006 验证用户名长度边界

lTC-007 验证密码长度边界

lTC-015 验证未登录用户访问登录后地址

没有手工测试用例。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-12-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 10.1.1 申请生成登录测试用例
  • 10.1.2 生成登录测试用例回复
    • 1)功能性测试
    • 2)边界情况测试
    • 3)安全性测试
    • 4)重定向测试
  • 10.1.3 更新测试用例
    • 1)功能性测试
    • 2)边界情况测试
    • 3)安全性测试
    • 4)重定向测试
  • 10.2 生成登录API测试用例
    • 10.2.1 申请登录API测试用例
    • 10.2.2登录API测试用例回复
      • 1)修改Util.py
    • 10.3.2 生成登录GUI测试用例回复
    • 10.3.3调整登录GUI测试程序
    • 10.3.4调整注册GUI测试程序
  • 10.4 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档