DEV Community

Cover image for Além do autocomplete: como o Cursor AI está ajudando na padronização e escrita do código Ruby on Rails
Cirdes Henrique
Cirdes Henrique

Posted on

3 2 2

Além do autocomplete: como o Cursor AI está ajudando na padronização e escrita do código Ruby on Rails

ENGLISH

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Imagem do Cursor aplicando a regra

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.

Erro de idioma nos testes gerados

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?

PR criado no GitHub

Hot sauce if you're wrong - web dev trivia for staff engineers

Hot sauce if you're wrong · web dev trivia for staff engineers (Chris vs Jeremy, Leet Heat S1.E4)

  • Shipping Fast: Test your knowledge of deployment strategies and techniques
  • Authentication: Prove you know your OAuth from your JWT
  • CSS: Demonstrate your styling expertise under pressure
  • Acronyms: Decode the alphabet soup of web development
  • Accessibility: Show your commitment to building for everyone

Contestants must answer rapid-fire questions across the full stack of modern web development. Get it right, earn points. Get it wrong? The spice level goes up!

Watch Video 🌶️🔥

Top comments (0)

AWS GenAI LIVE!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️