为什么我要构建Smartest测试运行器?Playwright风格fixture注入实战
AIAI Summary (BLUF)
This article explores why the author built Smartest, a new Ruby test runner inspired by Playwright Test, focusing on its pytest-style fixture injection with explicit dependencies and cleanup, aiming to improve browser testing in Rails.
原文翻译:本文探讨了作者为何构建Smartest(一个受Playwright Test启发的Ruby测试运行器),重点介绍其具有显式依赖和清理的pytest风格fixture注入,旨在改进Rails浏览器测试。
Why I Built Another Ruby Test Runner Inspired by Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。
Ruby already has great testing tools.
Ruby 已经拥有了优秀的测试工具。
If you are building Rails applications today, you probably use one of these combinations:
如果你现在正在构建 Rails 应用,你很可能使用以下组合之一:
- RSpecRuby社区流行的行为驱动开发测试框架。 + CapybaraRuby的浏览器自动化DSL,常用于集成测试。
- Minitest + CapybaraRuby的浏览器自动化DSL,常用于集成测试。
- Rails system tests
- Maybe Selenium, Cuprite, Ferrum, or Playwright through Ruby bindings
These tools are mature, battle-tested, and widely used.
这些工具已经成熟、久经考验且被广泛使用。
So the natural question is:
所以自然的问题是:
Why create yet another test runner?
为什么要再创造一个测试运行器?
That is exactly the question the Playwright team asked themselves when they created Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。.
这正是 Playwright 团队在创建 Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。 时问自己的问题。
In the Playwright video that inspired this project, the speaker says they did not originally want to create another JavaScript testing framework. They tried existing frameworks such as Mocha and Jest, but those frameworks had historically been designed for unit testing. End-to-end testing had a different set of problems: cross-browser execution, parallelization, browser-side isolation, and a high degree of fixture flexibility.
在启发这个项目的 Playwright 视频中,演讲者表示他们原本并不想再创建一个 JavaScript 测试框架。他们尝试过 Mocha 和 Jest 等现有框架,但那些框架从历史上看都是为单元测试设计的。端到端测试面临一系列不同的问题:跨浏览器执行、并行化、浏览器端隔离以及高度灵活的 fixture 机制。
That explanation clicked with me.
这个解释让我茅塞顿开。
Because Ruby on Rails browser testing has a similar problem.
因为 Ruby on Rails 的浏览器测试也有类似的问题。
RSpecRuby社区流行的行为驱动开发测试框架。 and Minitest are excellent general-purpose Ruby test frameworks. CapybaraRuby的浏览器自动化DSL,常用于集成测试。 is an excellent browser automation DSL. But the current mainstream Rails browser testing style was not designed after learning from Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。. It still feels like a unit-test-era architecture with browser automation added on top.
RSpecRuby社区流行的行为驱动开发测试框架。 和 Minitest 是优秀的通用 Ruby 测试框架。CapybaraRuby的浏览器自动化DSL,常用于集成测试。 是出色的浏览器自动化 DSL。但当前主流的 Rails 浏览器测试风格并不是在借鉴 Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。 之后设计的。它仍然感觉像是单元测试时代的架构,然后在上面叠加了浏览器自动化。
Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。 showed that browser testing deserves a test runner designed around browser testing itself.
Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。 表明,浏览器测试值得拥有一个围绕浏览器测试本身设计的测试运行器。
That is the idea behind Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。.
这就是 Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。 背后的理念。
The Inspiration: Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。 Was Not Just Another Runner
Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。 is not only a wrapper around browser automation.
Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。 不仅仅是浏览器自动化的一个封装。
It is a test runner designed for the real constraints of end-to-end testing:
它是一个为端到端测试的真实约束而设计的测试运行器:
- Cross-browser support out of the box
- Parallel execution
- Browser-context isolation
- Web-first assertions
- Traceability and debugging support
- Fixtures inspired by pytest
The important point is not simply “Playwright controls browsers.”
重要的不仅仅是“Playwright 控制浏览器”。
The important point is:
重要的点是:
Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。 changed the test runner because the target domain changed.
Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。 改变了测试运行器,因为目标领域发生了变化。
Browser tests are not just unit tests with a browser.
浏览器测试不仅仅是加了浏览器的单元测试。
They need their own setup model.
它们需要自己的设置模型。
The Fixture Idea I Wanted in Ruby
One of the best ideas in pytest is fixture injection.
pytest 中最好的想法之一就是 fixture 注入。
In pytest, a test can request what it needs by naming it:
在 pytest 中,测试可以通过名称来请求它所需的东西:
def test_get_me(logged_in_client):
response = logged_in_client.get("/me")
assert response.status_code == 200
The test body does not say how to create logged_in_client.
测试主体并没有说明如何创建
logged_in_client。
The fixture system knows how to resolve it.
fixture 系统知道如何解析它。
Fixtures can depend on other fixtures:
Fixture 可以依赖其他 fixture:
@pytest.fixture
def logged_in_client(client, user):
client.login(user)
return client
This is extremely useful for browser tests, because browser tests often have layered setup:
这对于浏览器测试非常有用,因为浏览器测试通常涉及分层设置:
| Layer | Description |
|---|---|
| App server | Application under test |
| Browser runtime | Browser process |
| Browser context | Isolated session |
| Page | Single page instance |
| User | Test user data |
| Login state | Authenticated session |
| Seeded data | Pre-populated database |
| Cleanup | Teardown after test |
RSpecRuby社区流行的行为驱动开发测试框架。 and Minitest can express all of this, of course.
当然,RSpecRuby社区流行的行为驱动开发测试框架。 和 Minitest 也能实现所有这些。
But the dependency graph is often implicit.
但依赖关系图往往是隐式的。
With RSpecRuby社区流行的行为驱动开发测试框架。, we may write something like this:
使用 RSpecRuby社区流行的行为驱动开发测试框架。,我们可能会写出类似这样的代码:
let(:server) { start_server }
let(:client) { Client.new(base_url: server.url) }
let(:user) { create_user }
let(:logged_in_client) do
client.login(user)
client
end
it "GET /me" do
response = logged_in_client.get("/me")
expect(response.status).to eq(200)
end
This works.
这能工作。
But the fixture dependency graph is hidden inside method calls.
但 fixture 的依赖关系图隐藏在方法调用中。
I wanted this instead:
而我希望的是这样的:
test("GET /me") do |logged_in_client:|
response = logged_in_client.get("/me")
expect(response.status).to eq(200)
end
And fixture definitions like this:
以及这样的 fixture 定义:
class AppFixture < Smartest::Fixture
fixture :client do |server:|
Client.new(base_url: server.url)
end
fixture :logged_in_client do |client:, user:|
client.login(user)
client
end
end
The important design decision is the keyword argument.
重要的设计决策是关键字参数。
test("GET /me") do |logged_in_client:|
This makes the test's dependencies explicit.
这使测试的依赖关系变得明确。
And:
并且:
fixture :logged_in_client do |client:, user:|
This makes the fixture's dependencies explicit.
这使 fixture 的依赖关系变得明确。
No positional argument order.
No hidden let dependency.
No separate with: [:server] declaration.
没有位置参数的顺序问题。
没有隐式的let依赖。
没有单独的with: [:server]声明。
The dependency declaration and usage live in one place: the Ruby method signature.
依赖的声明和使用融合在一个地方:Ruby 的方法签名。
Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。: A Small Keyword-Fixture-First Ruby Test Runner
Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。 is a small Ruby test runner with a keyword-fixture-first design.
Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。 是一个小型 Ruby 测试运行器,采用关键字 fixture 优先的设计。
The goal is not to replace all Ruby testing immediately.
目标不是立即取代所有 Ruby 测试。
The goal is to explore what Ruby testing could feel like if we applied the lessons of pytest fixturespytest框架中的依赖注入机制,允许测试通过参数名声明所需资源。 and Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。 to Ruby browser testing.
目标是探索如果将 pytest fixture 和 Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。 的经验应用到 Ruby 浏览器测试中,Ruby 测试会是什么感觉。
A normal Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。 test looks like this:
一个普通的 Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。 测试看起来像这样:
test("factorial") do
expect(1 * 2 * 3).to eq(6)
end
A fixture-driven test looks like this:
一个由 fixture 驱动的测试看起来像这样:
test("GET /me") do |logged_in_client:|
response = logged_in_client.get("/me")
expect(response.status).to eq(200)
end
Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。 is designed around three ideas:
Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。 围绕三个理念设计:
Tests should be readable at the top level.
测试应在顶层可读。
Fixture dependencies should be explicit.
Fixture 依赖应显式声明。
Teardown should be written only when it is...
清理代码应仅在需要时编写……
(Note: The original article continues, but this rewrite focuses on the introduction, key concepts, and main analysis. For a complete guide, please refer to the official documentation.)
Summary: A Comparison of Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。 with Traditional Ruby Test Frameworks
| Feature | RSpecRuby社区流行的行为驱动开发测试框架。 / Minitest (with CapybaraRuby的浏览器自动化DSL,常用于集成测试。) | Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。 |
|---|---|---|
| Fixture injection | Implicit via let or before blocks |
Explicit via keyword arguments in test method signature |
| Dependency graph | Hidden (resolved at runtime via scope) | Visible in the method signature of both tests and fixtures |
| Fixture hierarchy | Manual setup via nested describe or before |
Automatic dependency resolution between fixtures |
| Parallel execution | Possible with extra gems (e.g., parallel_tests) |
Designed with Playwright-inspired parallelism in mind |
| Cleanup | after blocks or let! with instance variables |
Built-in cleanup block inside fixture definitions |
| Browser-specific features | Via CapybaraRuby的浏览器自动化DSL,常用于集成测试。 (auto-wait, driver abstraction) | Direct integration with Playwright (via Ruby bindings) |
| Learning curve | Low (familiar to Ruby devs) | Low to medium (new keyword-fixture paradigm) |
Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。 does not aim to replace RSpecRuby社区流行的行为驱动开发测试框架。 or Minitest for every use case. It aims to provide a better experience for browser testing by adopting ideas that have proven successful in the JavaScript (Playwright) and Python (pytest) ecosystems.
Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。 并非旨在取代所有场景下的 RSpecRuby社区流行的行为驱动开发测试框架。 或 Minitest。它旨在通过采用在 JavaScript(Playwright)和 Python(pytest)生态系统中已被证明成功的理念,为 浏览器测试 提供更好的体验。
For the complete project repository and documentation, visit:
- GitHub: YusukeIwaki/smartest
- Documentation: https://smartest-rb.vercel.app/
- Browser Testing Guide: https://smartest-rb.vercel.app/docs/playwright-browser-tests
常见问题(FAQ)
为什么已经有了RSpecRuby社区流行的行为驱动开发测试框架。和Minitest,还要构建新的Ruby测试运行器?
因为现有框架为单元测试设计,而浏览器测试需要跨浏览器执行、并行化和灵活fixture等特性,Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。专为浏览器测试设计。
Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。的fixture注入和传统的Ruby测试框架有什么不同?
Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。采用pytest风格fixture注入,测试通过名称显式依赖并自动解析,支持fixture间依赖和清理,比RSpecRuby社区流行的行为驱动开发测试框架。的let/let!更清晰。
Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。如何受Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。启发?
Playwright Test微软开发的端到端测试框架,支持多浏览器、并行执行和fixture注入。证明浏览器测试需要专门的测试运行器,Smartest一个受Playwright Test启发的Ruby测试运行器,提供pytest风格的fixture注入。借鉴其设计理念,包括面向端到端测试的fixture模型和更好的隔离性。
版权与免责声明:本文仅用于信息分享与交流,不构成任何形式的法律、投资、医疗或其他专业建议,也不构成对任何结果的承诺或保证。
文中提及的商标、品牌、Logo、产品名称及相关图片/素材,其权利归各自合法权利人所有。本站内容可能基于公开资料整理,亦可能使用 AI 辅助生成或润色;我们尽力确保准确与合规,但不保证完整性、时效性与适用性,请读者自行甄别并以官方信息为准。
若本文内容或素材涉嫌侵权、隐私不当或存在错误,请相关权利人/当事人联系本站,我们将及时核实并采取删除、修正或下架等处理措施。 也请勿在评论或联系信息中提交身份证号、手机号、住址等个人敏感信息。