test-quality-inspector by bobmatnyc/claude-mpm-skills
npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill test-quality-inspector# test_user_registration.py
def test_user_creation():
"""测试用户创建"""
user = create_user("test@example.com", "password123")
assert user
def test_login():
"""测试登录"""
user = create_user("test@example.com", "password123")
result = login("test@example.com", "password123")
assert result
def test_duplicate_email():
"""测试重复邮箱"""
create_user("test@example.com", "password123")
user2 = create_user("test@example.com", "password456")
assert user2
声称意图: 测试用户创建 实际测试内容: 仅测试对象实例化
🔴 严重:无价值的断言
assert user # 第 5 行
思维调试: 包含垃圾数据的用户对象也能通过此测试。
🟠 高优先级:缺少验证测试
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
🟠 高优先级:缺少持久性验证
🟡 中优先级:测试名称模糊
def test_user_creation_with_valid_data_persists_to_database():
"""使用有效邮箱和密码创建用户应:
1. 创建具有正确属性的用户对象
2. 保存到数据库
3. 哈希密码(不存储明文)
4. 设置默认角色和激活状态
"""
email = "test@example.com"
password = "SecurePass123!"
user = create_user(email, password)
# 验证用户对象
assert user.id is not None, "创建后用户应具有 ID"
assert user.email == email, "邮箱应与输入匹配"
assert user.is_active is True, "新用户默认应处于激活状态"
assert user.role == "user", "新用户应具有 'user' 角色"
assert user.created_at is not None, "应设置创建时间戳"
# 验证密码已哈希,非明文
assert user.password_hash != password, "密码应被哈希"
assert len(user.password_hash) > 50, "密码哈希应具有足够长度"
# 验证持久性
retrieved_user = User.get_by_email(email)
assert retrieved_user is not None, "应能从数据库检索到用户"
assert retrieved_user.id == user.id, "检索到的用户应与创建的用户匹配"
def test_user_creation_with_invalid_email_format_raises_validation_error():
"""使用格式错误的邮箱创建用户应引发 ValidationError"""
invalid_emails = [
"not-an-email",
"@example.com",
"test@",
"test space@example.com",
"",
]
for invalid_email in invalid_emails:
with pytest.raises(ValidationError) as exc:
create_user(invalid_email, "password123")
assert "email" in str(exc.value).lower()
assert "invalid" in str(exc.value).lower()
def test_user_creation_with_weak_password_raises_validation_error():
"""使用弱密码创建用户应引发 ValidationError"""
weak_passwords = [
"123", # 太短
"password", # 无数字
"12345678", # 无字母
"", # 空
]
for weak_password in weak_passwords:
with pytest.raises(ValidationError) as exc:
create_user("test@example.com", weak_password)
assert "password" in str(exc.value).lower()
风险等级: 🔴 严重 操作: ❌ 阻止 - 核心功能未测试 预计修复时间: 30 分钟
声称意图: 测试登录 实际测试内容: 函数调用完成
🔴 严重:无价值的断言
assert result # 第 11 行
🔴 严重:缺少负面测试
🟠 高优先级:缺少会话验证
🟡 中优先级:测试依赖于之前的测试
@pytest.fixture
def registered_user():
"""为登录测试提供已注册用户的夹具"""
user = create_user("test@example.com", "SecurePass123!")
yield user
# 如果需要清理
User.delete(user.id)
def test_login_with_valid_credentials_returns_authenticated_session(registered_user):
"""使用正确的邮箱和密码登录应:
1. 返回认证令牌/会话
2. 设置认证状态
3. 包含用户上下文
4. 设置适当的过期时间
"""
session = login(registered_user.email, "SecurePass123!")
assert session is not None, "登录应返回会话"
assert session.is_authenticated is True, "会话应已认证"
assert session.user_id == registered_user.id, "会话应包含用户 ID"
assert session.token is not None, "会话应具有认证令牌"
assert session.expires_at > datetime.now(), "会话应具有未来的过期时间"
assert (session.expires_at - datetime.now()).seconds >= 3600, "会话应至少持续 1 小时"
def test_login_with_wrong_password_raises_authentication_error(registered_user):
"""使用错误密码登录应引发 AuthenticationError"""
with pytest.raises(AuthenticationError) as exc:
login(registered_user.email, "WrongPassword")
assert "Invalid credentials" in str(exc.value)
assert "password" in str(exc.value).lower()
def test_login_with_nonexistent_email_raises_authentication_error():
"""使用不存在的邮箱登录应引发 AuthenticationError"""
with pytest.raises(AuthenticationError) as exc:
login("doesnotexist@example.com", "password")
assert "Invalid credentials" in str(exc.value)
# 注意:不要透露邮箱是否存在(安全考虑)
def test_login_with_locked_account_raises_account_locked_error(registered_user):
"""登录锁定账户应引发 AccountLockedError"""
lock_account(registered_user.id)
with pytest.raises(AccountLockedError) as exc:
login(registered_user.email, "SecurePass123!")
assert registered_user.email in str(exc.value)
def test_login_with_empty_password_raises_validation_error(registered_user):
"""使用空密码登录应引发 ValidationError"""
with pytest.raises(ValidationError) as exc:
login(registered_user.email, "")
assert "password" in str(exc.value).lower()
assert "required" in str(exc.value).lower()
风险等级: 🔴 严重 操作: ❌ 阻止 - 认证未实际测试 预计修复时间: 45 分钟
声称意图: 测试重复邮箱处理 实际测试内容: 第二个用户创建成功(错误!)
🔴 严重:测试方向错误
user2 = create_user("test@example.com", "password456")
assert user2 # 第 17 行
🔴 严重:虚假信心
🟡 中优先级:与其他测试相同的邮箱问题
def test_create_user_with_duplicate_email_raises_integrity_error():
"""使用已存在的邮箱创建用户应:
1. 引发 IntegrityError 或 ValidationError
2. 不在数据库中创建重复用户
3. 保留现有用户数据
"""
email = "test@example.com"
# 创建第一个用户
user1 = create_user(email, "FirstPassword123!")
initial_count = User.count()
# 尝试创建重复用户
with pytest.raises((IntegrityError, ValidationError)) as exc:
create_user(email, "SecondPassword456!")
assert "email" in str(exc.value).lower()
assert "duplicate" in str(exc.value).lower() or "exists" in str(exc.value).lower()
# 验证未创建新用户
assert User.count() == initial_count, "用户数量不应增加"
# 验证原始用户未更改
original_user = User.get_by_email(email)
assert original_user.id == user1.id, "原始用户应保持完整"
assert original_user.verify_password("FirstPassword123!"), "原始密码应有效"
assert not original_user.verify_password("SecondPassword456!"), "新密码不应有效"
风险等级: 🔴 严重 操作: ❌ 阻止 - 测试验证了与需求相反的内容 预计修复时间: 20 分钟
测试套件质量: 🔴 失败
严重问题: 3
总测试数: 3 有效测试数: 0 覆盖率: 高(声称) 保护性: 无(实际)
生产风险: 🔴 极高
当前测试套件对以下情况提供零保护:
置信度: 0% - 测试通过毫无意义
总计: 1.5-2 天以获得适当的测试覆盖率
❌ 阻止合并
不要批准此 PR。测试提供虚假信心并掩盖严重错误。
证据:
后续步骤:
如果先编写测试:
# 首先编写此测试(它将失败):
def test_user_creation_with_valid_data_persists_to_database():
user = create_user("test@example.com", "password")
assert user.email == "test@example.com" # 在 create_user 正常工作前将失败
...
# 然后实现 create_user 使其通过
请参阅测试驱动开发技能以获取完整的 TDD 工作流程(可在技能库中获取全面的 TDD 指导)。
QA 检查员: [您的姓名] 日期: [日期] 状态: ❌ 拒绝 原因: 测试提供零保护,必须重写 需要重新检查: 是
这就是彻底的测试检查应有的样子。现在发现这些问题总比在生产环境中发现要好。
每周安装数
72
仓库
GitHub 星标数
18
首次出现
2026年1月23日
安全审计
安装于
claude-code56
gemini-cli55
opencode55
codex54
github-copilot51
cursor49
# test_user_registration.py
def test_user_creation():
"""Test user creation"""
user = create_user("test@example.com", "password123")
assert user
def test_login():
"""Test login"""
user = create_user("test@example.com", "password123")
result = login("test@example.com", "password123")
assert result
def test_duplicate_email():
"""Test duplicate email"""
create_user("test@example.com", "password123")
user2 = create_user("test@example.com", "password456")
assert user2
Claimed Intent: Test user creation Actually Tests: Object instantiation only
🔴 CRITICAL: Worthless Assertion
assert user # Line 5
Mental Debug: User object with garbage data would pass this test.
🟠 HIGH: Missing Validation Tests
🟠 HIGH: No Persistence Verification
🟡 MEDIUM: Vague Test Name
def test_user_creation_with_valid_data_persists_to_database():
"""Creating a user with valid email and password should:
1. Create user object with correct attributes
2. Save to database
3. Hash password (not store plaintext)
4. Set default role and active status
"""
email = "test@example.com"
password = "SecurePass123!"
user = create_user(email, password)
# Verify user object
assert user.id is not None, "User should have an ID after creation"
assert user.email == email, "Email should match input"
assert user.is_active is True, "New users should be active by default"
assert user.role == "user", "New users should have 'user' role"
assert user.created_at is not None, "Created timestamp should be set"
# Verify password is hashed, not plaintext
assert user.password_hash != password, "Password should be hashed"
assert len(user.password_hash) > 50, "Password hash should be substantial"
# Verify persistence
retrieved_user = User.get_by_email(email)
assert retrieved_user is not None, "User should be retrievable from database"
assert retrieved_user.id == user.id, "Retrieved user should match created user"
def test_user_creation_with_invalid_email_format_raises_validation_error():
"""Creating a user with malformed email should raise ValidationError"""
invalid_emails = [
"not-an-email",
"@example.com",
"test@",
"test space@example.com",
"",
]
for invalid_email in invalid_emails:
with pytest.raises(ValidationError) as exc:
create_user(invalid_email, "password123")
assert "email" in str(exc.value).lower()
assert "invalid" in str(exc.value).lower()
def test_user_creation_with_weak_password_raises_validation_error():
"""Creating a user with weak password should raise ValidationError"""
weak_passwords = [
"123", # Too short
"password", # No numbers
"12345678", # No letters
"", # Empty
]
for weak_password in weak_passwords:
with pytest.raises(ValidationError) as exc:
create_user("test@example.com", weak_password)
assert "password" in str(exc.value).lower()
Risk Level: 🔴 CRITICAL Action: ❌ BLOCK - Core functionality not tested Estimated Fix Time: 30 minutes
Claimed Intent: Test login Actually Tests: Function call completes
🔴 CRITICAL: Worthless Assertion
assert result # Line 11
🔴 CRITICAL: Missing Negative Tests
🟠 HIGH: No Session Verification
🟡 MEDIUM: Test Depends on Previous Test
@pytest.fixture
def registered_user():
"""Fixture providing a registered user for login tests"""
user = create_user("test@example.com", "SecurePass123!")
yield user
# Cleanup if needed
User.delete(user.id)
def test_login_with_valid_credentials_returns_authenticated_session(registered_user):
"""Logging in with correct email and password should:
1. Return authentication token/session
2. Set authenticated state
3. Include user context
4. Set appropriate expiry
"""
session = login(registered_user.email, "SecurePass123!")
assert session is not None, "Login should return session"
assert session.is_authenticated is True, "Session should be authenticated"
assert session.user_id == registered_user.id, "Session should contain user ID"
assert session.token is not None, "Session should have authentication token"
assert session.expires_at > datetime.now(), "Session should have future expiry"
assert (session.expires_at - datetime.now()).seconds >= 3600, "Session should last at least 1 hour"
def test_login_with_wrong_password_raises_authentication_error(registered_user):
"""Logging in with incorrect password should raise AuthenticationError"""
with pytest.raises(AuthenticationError) as exc:
login(registered_user.email, "WrongPassword")
assert "Invalid credentials" in str(exc.value)
assert "password" in str(exc.value).lower()
def test_login_with_nonexistent_email_raises_authentication_error():
"""Logging in with non-existent email should raise AuthenticationError"""
with pytest.raises(AuthenticationError) as exc:
login("doesnotexist@example.com", "password")
assert "Invalid credentials" in str(exc.value)
# Note: Don't reveal if email exists (security)
def test_login_with_locked_account_raises_account_locked_error(registered_user):
"""Logging in to locked account should raise AccountLockedError"""
lock_account(registered_user.id)
with pytest.raises(AccountLockedError) as exc:
login(registered_user.email, "SecurePass123!")
assert registered_user.email in str(exc.value)
def test_login_with_empty_password_raises_validation_error(registered_user):
"""Logging in with empty password should raise ValidationError"""
with pytest.raises(ValidationError) as exc:
login(registered_user.email, "")
assert "password" in str(exc.value).lower()
assert "required" in str(exc.value).lower()
Risk Level: 🔴 CRITICAL Action: ❌ BLOCK - Authentication not actually tested Estimated Fix Time: 45 minutes
Claimed Intent: Test duplicate email handling Actually Tests: Second user creation succeeds (WRONG!)
🔴 CRITICAL: Test is Backwards
user2 = create_user("test@example.com", "password456")
assert user2 # Line 17
🔴 CRITICAL: False Confidence
🟡 MEDIUM: Same Email Issue as Other Tests
def test_create_user_with_duplicate_email_raises_integrity_error():
"""Creating a user with an email that already exists should:
1. Raise IntegrityError or ValidationError
2. Not create duplicate user in database
3. Preserve existing user data
"""
email = "test@example.com"
# Create first user
user1 = create_user(email, "FirstPassword123!")
initial_count = User.count()
# Attempt to create duplicate
with pytest.raises((IntegrityError, ValidationError)) as exc:
create_user(email, "SecondPassword456!")
assert "email" in str(exc.value).lower()
assert "duplicate" in str(exc.value).lower() or "exists" in str(exc.value).lower()
# Verify no new user created
assert User.count() == initial_count, "User count should not increase"
# Verify original user unchanged
original_user = User.get_by_email(email)
assert original_user.id == user1.id, "Original user should be intact"
assert original_user.verify_password("FirstPassword123!"), "Original password should work"
assert not original_user.verify_password("SecondPassword456!"), "New password should not work"
Risk Level: 🔴 CRITICAL Action: ❌ BLOCK - Test verifies opposite of requirement Estimated Fix Time: 20 minutes
Test Suite Quality: 🔴 FAILING
Critical Issues: 3
Total Tests: 3 Effective Tests: 0 Coverage: High (claims) Protection: None (reality)
Production Risk: 🔴 EXTREME
Current test suite provides zero protection against:
Confidence Level: 0% - Tests passing means nothing
Total: 1.5-2 days for proper test coverage
❌ BLOCK MERGE
Do not approve this PR. Tests provide false confidence and mask critical bugs.
Evidence:
Next Steps:
If tests were written first:
# Write this FIRST (it will fail):
def test_user_creation_with_valid_data_persists_to_database():
user = create_user("test@example.com", "password")
assert user.email == "test@example.com" # Will fail until create_user works
...
# Then implement create_user to make it pass
See the Test-Driven Development skill for complete TDD workflow (available in the skill library for comprehensive TDD guidance).
QA Inspector: [Your name] Date: [Date] Status: ❌ REJECTED Reason: Tests provide zero protection, must be rewritten Re-inspection Required: Yes
This is what thorough test inspection looks like. Better to catch these issues now than in production.
Weekly Installs
72
Repository
GitHub Stars
18
First Seen
Jan 23, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code56
gemini-cli55
opencode55
codex54
github-copilot51
cursor49
后端测试指南:API端点、业务逻辑与数据库测试最佳实践
11,800 周安装
React TanStack 高级开发者技能指南:状态管理、路由、表单与项目架构最佳实践
98 周安装
Claude本地分析工具:跨项目隐私安全数据分析与性能监控
98 周安装
Gemini CLI 技能:本地命令行工具,集成Google Gemini AI进行代码分析、头脑风暴与安全沙箱执行
98 周安装
CLAUDE.md 架构师技能:为软件项目生成和优化 AI 项目指令文件,提升 Claude 代码效率
98 周安装
PlantUML 语法参考大全:15+图表类型快速上手,从UML到C4架构图
98 周安装
React 19、Next.js 16、Vue 3.5 前端开发专家 - 现代Web应用与组件架构模式
98 周安装