This article will cover creating integration tests using Rails 6 Active Storage. It will include the create and edit actions.
Scaffold out the model.
$ rails g scaffold Profile name:string
Update the model/profile.rb to include a profile picture.
class Profile < ApplicationRecord
    has_one_attached :profile_picture
end
Update the views/profiles/_form.html.erb to include a input for the profile picture.
<div class="field">
    <%= form.label :profile_picture %>
    <%= form.file_field :profile_picture %>
</div>
Update the controllers/profile_controller.rb to allow for the profile_picture params.
def profile_params
    params.require(:profile).permit(:name, :profile_picture)
end
Add the integration test settings to test_helper.rb.
require 'capybara/minitest'
class ActionDispatch::IntegrationTest
    # Make the Capybara DSL available in all integration tests
    include Capybara::DSL
    # Make `assert_*` methods behave like Minitest assertions
    include Capybara::Minitest::Assertions
    def setup
        Capybara.default_driver = :selenium_chrome_headless
        Capybara.default_max_wait_time = 5
    end
    # Reset sessions and driver between tests
    # Use super wherever this method is redefined in your individual test classes
    def teardown
        Capybara.reset_sessions!
        Capybara.use_default_driver
        Capybara.default_max_wait_time = 2
    end
end
Create a file called test/integration/profile_integration_test.rb and add the first test to create a profile. Remember to add a picture called picture_one.jpg to the test directory.
# frozen_string_literal: true
require 'test_helper'
class ProfileIntegrationTest < ActionDispatch::IntegrationTest
    test 'that a profile can be created' do
        visit new_profile_path
        fill_in "Name", with: 'Jane Doe'
        find(:css, '#profile_profile_picture').set(File.join(Rails.root + "test", 'picture_one.jpg'))
        click_button 'Create Profile'
        assert_current_path profile_path(Profile.order("created_at").last)
        assert_equal ActiveStorage::Attachment.count, 1
    end
end
Add a fixture to test/fixtures/profile.yml to represent the profile.
remove_existing_profile_picture:
    name: 'Jane Doe'
We need to add an attribute to the model which we can use to determine if the profile picture should be removed or not.
class Profile < ApplicationRecord
    has_one_attached :profile_picture
    attr_accessor :remove_existing_profile_picture
end
Update the controller to allow for the new parameter.
def profile_params
    params.require(:profile).permit(:name, :profile_picture, :remove_existing_profile_picture)
end
Update the form to show the remove profile picture checkbox, but only if a picture is attached.
<% if profile.profile_picture.attached? %>
    <%= form.label :remove_existing_profile_picture %>
    <%= form.check_box :remove_existing_profile_picture %>
<% end %>
Update the controller to check for the remove_existing_profile_picture and remove the profile picture.
def update
   if profile_params[:remove_existing_profile_picture] == "1"
     @profile_picture = @profile.profile_picture
     @profile_picture.purge_later
   end
   ...
end
Add the integration test to remove the profile picture.
test 'that a profile picture can be removed ' do
   profile = profiles(:remove_existing_profile_picture)
   profile.profile_picture.attach(
       io: File.open(File.join(Rails.root + "test", 'picture_one.jpg')), 
       filename: 'picture_one.JPG', content_type: 'image/jpeg'
   )
   profile.save!
   visit edit_profile_path(profile)
   find(:css, "#profile_remove_existing_profile_picture").set(true)
   click_button 'Update Profile'
   assert_equal ActiveStorage::Attachment.count, 0
end