Search code examples
ruby-on-railsjmeterruby-jmeter

How to write jmeter test to submit a form within website (Jmeter, ruby -jmeter)


I am writing a load test for my application.

I would like to simulate the following steps:

  1. login
  2. visit several pages
  3. submit a form within the website

I first wrote the login and visit several pages and run them successfully (no errors). When I added the code to submit form, I was getting '404/Not Found error' for the Submit Abstract transaction.

I am grateful to anyone who can provide me direction on how to solve this.

I wrote this test script using ruby then execute to convert it to .jmx file which I use to run headless test in cli.

code for login and visit several pages:

require 'ruby-jmeter'

test do
  threads count: 100, rampup: 60, loops: 10, duration: 120 do
    defaults domain: 'myapp.herokuapp.com', protocol: 'https'
    cookies policy: 'rfc2109', clear_each_iteration: true

    transaction 'Page Load Tests' do
      user_defined_variables [{name: 'email', value: '[email protected]'}, {name: 'password', value: 'Pass_w0rd'}]
      visit name: 'Visit Login', url: '/users/sign_in' do
        extract name: 'csrf-token', xpath: "//meta[@name='csrf-token']/@content", tolerant: true
        extract name: 'csrf-param', xpath: "//meta[@name='csrf-param']/@content", tolerant: true
        extract name: 'authenticity_token', regex: 'name="authenticity_token" value="(.+?)"'
      end
    end

    http_header_manager name: 'X-CSRF-Token', value: '${csrf-token}'
    submit name: 'Submit login', url: '/users/sign_in',
     fill_in: {
       '${csrf-param}' => '${csrf-token}',
       'user[email]' => '${email}',
       'user[password]' => '${password}',
       'authenticity_token' => '${authenticity_token}'
      }
    visit name: 'Welcome Page', url: '/static_pages/welcome'
    visit name: 'New Abstract Page', url: '/users/2/abstracts/new'
    visit name: 'My Profile Page', url:'/users/2/participations/1/profile'
    visit name: 'My Own Abstract Page', url:'/users/2/participations/1/abstracts/1'

  view_results_in_table
  aggregate_report
end.jmx

code for login, visit pages and submit form:

require 'ruby-jmeter'

test do
  threads count: 100, rampup: 60, loops: 10, duration: 120 do
    defaults domain: 'myapp.herokuapp.com', protocol: 'https'
    cookies policy: 'rfc2109', clear_each_iteration: true

    transaction 'Page Load Tests' do
      user_defined_variables [{name: 'email', value: '[email protected]'}, {name: 'password', value: 'Pass_w0rd'}]
      visit name: 'Visit Login', url: '/users/sign_in' do
        extract name: 'csrf-token', xpath: "//meta[@name='csrf-token']/@content", tolerant: true
        extract name: 'csrf-param', xpath: "//meta[@name='csrf-param']/@content", tolerant: true
        extract name: 'authenticity_token', regex: 'name="authenticity_token" value="(.+?)"'
      end
    end

    http_header_manager name: 'X-CSRF-Token', value: '${csrf-token}'
    submit name: 'Submit login', url: '/users/sign_in',
     fill_in: {
       '${csrf-param}' => '${csrf-token}',
       'user[email]' => '${email}',
       'user[password]' => '${password}',
       'authenticity_token' => '${authenticity_token}'
      }
    visit name: 'Welcome Page', url: '/static_pages/welcome'
    visit name: 'New Abstract Page', url: '/users/2/abstracts/new'
    visit name: 'My Profile Page', url:'/users/2/participations/1/profile'
    visit name: 'My Own Abstract Page', url:'/users/2/participations/1/abstracts/1'

    transaction 'Submit Abstract' do
      visit name: 'New Abstract Page', url: '/users/2/abstracts/new' do
        extract name: 'csrf-token', xpath: "//meta[@name='csrf-token']/@content", tolerant: true
        extract name: 'csrf-param', xpath: "//meta[@name='csrf-param']/@content", tolerant: true
        extract name: 'authenticity_token', regex: 'name="authenticity_token" value="(.+?)"'
      end

      http_header_manager name: 'X-CSRF-Token', value: '${csrf-token}'
      submit name: 'Submit Abstract', url: '/users/2/abstracts/new',
        fill_in: {
          '${csrf-param}' => '${csrf-token}',
          'abstract[title]' => 'Lorem Ipsum',
          'abstract[main_author]' => '2',
          'abstract[co_authors][]' => ["", "1", "3"],
          'abstract[corresponding_author_email]' => '${email}',
          'abstract[keywords]' => 'word, words',
          'abstract[body]' => 'The test directive is a root point, where all the magic starts. Then, using threads method we are telling JMeter what number of users we want to use. The defaults command allows us to specify default options for all our http requests. And, finally,cookies indicates that we need to store cookies and send them with each request.',
          'abstract[references]' => '1\r\n2\r\n3',
          'authenticity_token' => '${authenticity_token}'
        } do
          assert 'contains' => 'Abstract submission completed.'
          assert 'contains' => 'Lorem Ipsum'
      end
    end
  end

  view_results_in_table
  aggregate_report
end.jmx

UPDATE PER @DMITRI T SUGGESTION:

EDITED TEST enter image description here

REQUEST HEADER:

Browser:

enter image description here enter image description here

Jmeter:

enter image description here

REQUEST BODY:

Browser:

enter image description here enter image description here

Jmeter:

enter image description here

RESULT: STILL 404 error for the Submit Abstract Transaction

enter image description here


Solution

  • HTTP Status 404 means that the server cannot find the requested resource so most probably your URL is wrong.

    So double check that the URL of https://myapp.herokuapp.com/users/2/abstracts/new returns a valid response for the logged in user and if it does - capture the request for creating the new "abstract" using your browser developer tools

    Then in JMeter GUI:

    1. Change number of threads, ramp-up period and loop count to 1 in the https://jmeter.apache.org/usermanual/component_reference.html#Thread_Group

      enter image description here

    2. Add Debug Post-Processor to your Test Plan (it will allow you to see the values of JMeter Variables)

    3. Add View Results Tree listener to your Test Plan (it will allow to see the request and response details)

    4. Run your test in JMeter GUI, inspect Submit Abstract request details and cross-check it with what you see in the browser developer tools - the requests must be absolutely the same (apart from dynamic parameters)

      enter image description here

    5. Fix your JMeter configuration so it would send exactly the same request and it should resolve your issue.