Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lessons learned from a huge Rails app - RubyConf Brasil 2019

Lessons learned from a huge Rails app - RubyConf Brasil 2019

A set of experiences working on a very challenging project, with a domain model constantly evolving, 24/7 availability, multiple teams working in the same codebase, integration with many external services, and so on.
In this talk we'll try go through these experiences, focusing on these questions: How do we approach new features? How do we deal with tech debt or any other risks? What can we do to speed up delivery? Is Rails helping us to achieve our goals? How should be our testing strategy? How do we handle production errors?

Nahuel Garbezza

December 27, 2020
Tweet

More Decks by Nahuel Garbezza

Other Decks in Programming

Transcript

  1. Ways to measure an application size > Rails::Engine.subclasses.sum { |e|

    e.routes.routes.size } => 1554 Bundle complete! 234 Gemfile dependencies, 459 gems now installed.
  2. /lib $ tree lib/ lib/ ├── additional_params.rb ├── address_validator.rb ├──

    aol_integration.rb ├── api_throttled_client.rb ├── bad_login_detector.rb ├── cache_keys_invalidator.rb ├── command_interpreter.rb ├── customer_survey.rb ├── default_operation.rb ├── html_errors_formatter.rb ├── json_to_xml_to_json.rb ├── log_middleware.rb ├── measure_converter.rb ├── money_helper.rb ├── one_time_activation.rb ├── product_selector.rb ├── profit_calculator.rb ├── registration_step.rb ├── sharing_policy.rb ├── stuff.rb ├── unknown_identity.rb ├── url_generator.rb ├── user_search_result.rb ├── world_changer.rb ├── xml_utilities.rb └── ...
  3. build a test suite you can trust class Conference <

    ApplicationRecord has_many :attendants end class Attendant < ApplicationRecord belongs_to :conference end “Self-growing” test: check for factories validity FactoryBot.define do factory :conference do title { 'RubyConfBR 2019' } description { 'foo' } end factory :attendant do name { ‘Nahuel’ } conference end end
  4. build a test suite you can trust class FactoriesValidityTest <

    ActiveSupport::TestCase all_factory_names = FactoryBot.factories.map(&:name) all_factory_names.each do |factory_name| test "factory #{factory_name} creates a valid object" do instance = FactoryBot.build(factory_name) assert_equal true, instance.valid? end end end “Self-growing” test: check for factories validity 1 test running N different instances
  5. build a test suite you can trust class Conference <

    ApplicationRecord has_many :attendants validates :description, length: { minimum: 20 } end class Attendant < ApplicationRecord belongs_to :conference end “Self-growing” test: check for factories validity FactoryBot.define do factory :conference do title { 'RubyConfBR 2019' } description { 'foo' } end factory :attendant do name { ‘Nahuel’ } conference end end Oops
  6. build a test suite you can trust class FactoriesValidityTest <

    ActiveSupport::TestCase all_factory_names = FactoryBot.factories.map(&:name) all_factory_names.each do |factory_name| test "factory #{factory_name} creates a valid object" do instance = FactoryBot.build(factory_name) assert_equal true, instance.valid? end end end “Self-growing” test: check for factories validity Feedback about problems in one of our factories
  7. build a test suite you can trust Mutation Testing expecting

    the tests to fail https://github.com/mbj/mutant Testing our tests with Mutation Testing