Contexto
Até pouco tempo atrás, além da capacidade de autocompletar código, eu ainda não tinha visto uma forma realmente confiável de gerar código com IA que fosse útil para minha empresa, a Linkana.
Concordo com o DHH quando ele diz que a IA é apenas um excelente programador júnior, que por vezes pode gerar um código excessivamente complexo ou introduzir bugs quase imperceptíveis. Se no futuro isso será diferente, não sabemos. O que importa é que, hoje, podemos fornecer um bom contexto para que a IA nos ajude a escrever código de qualidade.
Cursor AI
Em setembro do ano passado, o Rafael França (Rails Core) passou alguns dias em São Paulo e me mostrou que estava usando o Cursor no lugar do VSCode. Decidi migrar para o Cursor AI e, desde então, tenho aproveitado sua melhor capacidade de autocomplete e a funcionalidade de explicar trechos de código. Até então, nada muito sofisticado.
Cursor Rules
Nas últimas semanas, conheci a funcionalidade de Rules for AI, uma maneira de ensinar à IA como ela deve "pensar". Dessa forma, conseguimos orientar o Cursor a agir como um bom desenvolvedor júnior se comportaria, reconhecendo padrões de código, replicando-os em contextos semelhantes e garantindo consistência no projeto.
Migrando de RSpec para MiniTest
No ano passado, decidimos migrar para MiniTest. Passamos a escrever novos testes em MiniTest, mas ainda temos centenas de arquivos escritos em RSpec. Como era de se esperar, ninguém quer priorizar a reescrita de testes, o que tornou essa migração extremamente lenta.
Para acelerar esse processo, criamos uma estrutura semelhante a esta, permitindo definir regras específicas para diferentes contextos do nosso código:
.cursor/rules/
├── rails8.mdc
├── models/
│ ├── active_record.mdc
│ ├── tests.mdc
│ └── postgresql.mdc
├── controllers/
│ ├── api.mdc
│ └── tests.mdc
└── views/
├── phlex.mdc
└── components.mdc
Vamos dar uma olhada no models/tests.mdc
:
---
description: ""
globs: test/models/**/*.rb
alwaysApply: true
---
# Rails Model Testing with Minitest and FactoryBot
## General Structure
- Each model should have its own corresponding test file (e.g., `user_test.rb` for the `User` model)
- Test files should be organized within the `test/models` directory, mirroring the application structure
- Subdirectories can be used to organize specific components (e.g., `test/models/documents/`)
## Test Configuration and Organization
- Each file should include `require "test_helper"` at the beginning
- The test class should inherit from `ActiveSupport::TestCase`
- Tests should be written using `test "description" do` instead of `def test_description`
- Related tests should be grouped together
- The `setup` method should be used to create test data with factories
## Using Factories
- Factories should be defined in `test/factories/`
- Use `create(:factory_name)` for persisted records and `build(:factory_name)` for non-persisted ones
- Use `build_stubbed(:factory_name)` when persistence is not needed
- Use descriptive traits for factory variations (e.g., `:with_buyer`, `:not_clear`)
## Example Structure
# frozen_string_literal: true
require "test_helper"
class ModelNameTest < ActiveSupport::TestCase
def setup
@model = create(:model_name, :with_trait)
end
test "associations" do
assert_respond_to(@model, :association_name)
# Test other associations...
end
test "validations" do
invalid_model = build(:model_name, required_attribute: nil)
refute(invalid_model.valid?)
assert_equal(invalid_model.errors[:required_attribute], ["expected error message"])
end
end
## Style and Best Practices
- Tests should be independent and isolated
- Avoid fixtures whenever possible, preferring factories
- Use meaningful test data to clearly express intent
- Test edge cases and failure scenarios
- Follow the "Arrange, Act, Assert" pattern
- Cover both positive and negative cases
Podemos notar que essa regra define padrões como o uso de factories, a organização dos testes, e o formato das declarações test "instance_method" do
. Além de guiar a IA na escrita dos testes, essas regras também ajudam a manter a padronização do projeto e servem como documentação de boas práticas tanto para a equipe humana quanto para a própria IA.
O mais interessante é que consegui gerar essa rule com um único prompt no Cursor. Forneci a documentação e exemplos do meu próprio código, e a IA criou as instruções automaticamente – precisei apenas ajustar alguns detalhes.
Utilizando na prática
Com as regras definidas, chegou a hora de testar na prática. Ao solicitar que o Cursor fizesse a migração de um teste de RSpec para MiniTest, ele identificou automaticamente a regra aplicável com base no globs: test/models/**/*.rb
.
Para validar o processo, fiz a migração arquivo por arquivo. O único erro que encontrei foi relacionado ao idioma: o Cursor esperava mensagens de erro em inglês, mas minha aplicação está em português.
No final, consegui abrir um Pull Request com baixíssimo esforço e com a qualidade esperada. Será que esse PR vai ser mergeado sem pedidos de correção?
Top comments (0)