单位vs集成测试
1)为什么要区分测试类型
正确的测试粒度使开发可预测:单位快速廉价地捕获逻辑缺陷;集成测试模块捆绑、实际传输和"粘合剂"。他们一起减少了倒退并加快了发行速度。
2)定义和界限
单位测试
隔离检查小行为单位(函数、类、用例)。
已更换外部约束(mock/stub/fake)。
快速(ms-xx ms),确定性。
集成测试
检查多个实际组件的交互:DB、经纪人(Kafka/RabbitMQ)、HTTP/gRPC、文件系统、缓存。
最低限度的莫克,真正的协议。
速度更慢(数百毫秒),支持成本更高。
3)测试金字塔(不是冰角)
基础:单位(数量为70-80%)-便宜,快速。
中层:Integration/Component (15-25%)-关键路径和合同。
顶部:E2E/UX/Exploratory(5-10%)-最低限度就足够了。
侧面:静态分析/Lint/类型检查和模拟测试作为质量放大器。
4)给单位什么,什么是整合
5)数据和虚构
Unit
Inline fixtures/售票员(工厂方法)。
边界值的表测试(table driven)。
不变量的基于属性的方法(例如,"借方总和=借方总和")。
Integration
Hermetic环境:Testcontainers/Docker Compose提出"postgres+redis+kafka+wiremock"。
在DB/缓存中初始种子,并在之后清除(事务/滚回,跟踪器)。
时钟/计时器是假的(受控的),否则是小瓶。
6)工具和模式
Mocks/Stubs/Fakes/Spies:
Stub是固定响应(便宜)。
Mock-验证交互/呼叫数。
Fake是一种简化的实现(例如In-Memory Repo)。
合同测试(CDC):基于客户的Pact/Swagger-捕获客户期望并检查提供商。
WireMock/MockServer是用于第三方服务的HTTP存根。
Testcontainers是本地和CI中没有"动物园"的现场DB/经纪人。
7)示例
7.1单位:支付水平性(pseudocode)
python def test_idempotent_create_payment_returns_same_id():
repo = InMemoryPayments()
service = Payments(repo)
first = service. create(amount=100, key="abc")
second = service. create(amount=100, key="abc")
assert first. id == second. id assert repo. count() == 1
7.2 Integration: webhook签名(HMAC)+重播
bash docker-compose: app + redis + wiremock (PSP)
docker compose -f docker-compose. test. yml up -d pytest -m "integration and webhook" -q
测试:
- WireMock用"X-Timestamp"和签名给出了事件。
- 应用程序检查HMAC,通过"event_id"进行重复消除,5秒钟后的重播不会产生双倍。
- 我们检查"200"并且记录是唯一的。
7.3 CDC:客户与提供商的合同
客户形成Pact(等待:"POST/v1/payout" → "201"带有电路)。
CI的提供商在其展位上运行合同验证。
8)速度,平行度,长笛
单位必须工作<100毫秒;数据包-秒。
整合-跨容器/端口并行;在启动时使用迁移。
- 受控时间(假时钟),
- "对显式事件的期望"而不是"睡眠",
- 稳定的阈值(带有抖动器的转子进行确定性测试)。
9)质量指标
Coverage(行/分支):有利于观察趋势,但不适用于目标。
Mutation testing (PIT/Mutmut):显示测试是否"杀死"虚假变化是关联的真正力量。
Test duration and flaky rate:生长时的差异。
防御集合:在生产前截获的错误比例。
10)嵌入到CI/CD中
Jobs:单位→ integration → e2e(服务粉丝)。
依存缓存,与DB/语言/版本的矩阵并行。
报告:JUnit/Allure+容器日志工件(跌落时)。
Gate:"绿色单位+关键集成"-警戒条件;e2e-在夜间。
yaml strategy:
matrix:
db: [postgres14, postgres16]
steps:
- run: docker run -d --name db -e POSTGRES_PASSWORD=pw postgres:${{ matrix. db }}
- run: pytest -m "unit" -q
- run: pytest -m "integration" -q
11)微服务与活动
服务合同:OpenAPI/Protobuf转换;兼容性测试(背面)。
Event-driven:
单位:映射域事件和不变量。
整合:真实经纪人(Kafka)发布/订阅,outbox/inbox语义,单次模仿(至少是idempotent)。
复制/复制/重新排序(订单外部)测试。
12)集成中的数据和隔离
每个测试都→ 独特的电路/DB(Testcontainers JDBC URL'?TC_TMPFS =/var/lib/postgresql/data:rw')。
交易伪造(begin→run→rollback)加快了清洁。
对于Redis/缓存,关键前缀是"test: ${RUN_ID}:"和"FLUSHDB"。
13) iGaming/财务细节
金钱和限制:基于属性的不变量测试(余额≥ 0,总限制)。
监管:日志验证(审计日志写),不可变事件。
付款/PSP:HMAC/mTLS集成测试,"Retry-After",幂等,dedup'jti'。
负责任的游戏:阈值/拳头规则测试;fake clock上的"vchera→segodnya"。
14)反模式
提高DB/NTTR的"单位"已经是整合(混淆层并减慢CI)。
高覆盖率以空白陈述为代价("覆盖但未验证")。
在需要合同的地方清洗第三方服务逻辑(更新时中断)。
使用"sleep (5)"测试而不是对事件/条件的期望。
用于并行测试→比赛和长笛的一般测试DB。
15)准备就绪支票清单
- 金字塔定义为:按运行时间计算的Unit/Integration/E2E份额和目标的百分比。
- 单位是隔离的,快速的,覆盖边界值和不变量。
- Integration使用恒温环境(Testcontainers/Compose),没有共享状态。
- 合同测试(OpenAPI/Pact)在CI中进行了验证。
- 测试数据-可管理:seed/rollback/前缀, fake clock。
- 并行运行、JUnit/Allure报告、容器日志工件。
- 度量标准:持续时间,flaky rate, mutation分数;降解的差异。
- 支付/webhook脚本:HMAC/mTLS, retrais, Idempentity, dedup。
- 策略文档和测试模板示例。
16) TL;DR
单位-逻辑的最大值,环境的最小值;Integration是moks的最小值,是现实主义的最大值。保持金字塔:快速单元捕获80%的缺陷,Integration确认韧带和合同。使用恒温容器、合同测试、假时钟和并发性。不仅要测量覆盖率,还要测量比分和比例。特别检查付款/网络挂钩路径:签名、转发和等效性。