Using Timing Statistics to Optimize Tests

Would you want to make your tests run faster?

rflogs.io offers Timing Statistics as part of normal run details. This information gives you visibility into where time in Robot Framework runs is actually spent. It tracks times on 3 levels: suites, tests and keywords. This means that you can easily visualize what tests are consuming most of the time, and also which keywords are the most time-intensive.

Let's jump into Robot Framework Browser tests that were introduced in Optimizing the CI/CD Pipeline for Robot Framework Browser Using Pabot and RF Logs and see if we can spot anything to improve.

Analyzing the Shards

Robot Framework Browser tests are split into 4 shards and we can look at each shard separately.

Shard 1 Recent Results (153 tests)

Total Suite Time: 61.212s
Browser.New Page 35.901s (133 calls, avg 0.270s)
Test.01 Browser Management.Playwright State 34.568s
Test.01 Browser Management 18.365s
New Page Should Not Timeout 12.637s
BuiltIn.Run Keyword And Expect Error 11.348s (32 calls)
Launch Browser Server Via CLI 10.983s
BuiltIn.Sleep 10.610s (2 calls, avg 5.305s)

Shard 2 Recent Results (290 tests)

Total Suite Time: 54.084s
Browser.New Page 30.996s (282 calls, avg 0.110s)
Test.02 Content Keywords.Files 23.939s
Test.01 Browser Management 21.282s
BuiltIn.Run Keyword And Expect Error 20.685s (100 calls)
Upload Large File As Buffer 11.729s
Generate Test Text File 9.601s
String.Generate Random String 9.587s

Shard 3 Recent Results (218 tests)

Total Suite Time: 114.326s
Test.03 Waiting 102.599s
Test.02 Content Keywords 74.329s
Wait For Http 44.875s
BuiltIn.Run Keyword And Expect Error 38.630s (58 calls)
Virtual Mouse Tests 35.347s
Wait For Element State 29.699s
Drag And Drop With Coordinates 23.903s

Shard 4 Recent Results (106 tests)

Total Suite Time: 72.421s
Test.08 Scope Tests 52.301s
Browser.Get Element States 33.889s (56 calls)
BuiltIn.Run Keyword And Expect Error 24.435s (35 calls)
Browser.Wait For Condition 20.637s (43 calls)
Timeout/Assertion Retry checks ~39s (combined)

Identified Optimization Targets

From analyzing the timing data, several high-impact optimization opportunities emerged:

  1. Static Sleep Operations
  2. File Generation Performance
  3. Browser Server Launch Strategy

Let's look at how we can improve each of these.

1. File Generation Optimization

The original implementation had performance issues:

Generate Test Text File
    [Arguments]    ${length_of_text}
    ${filename} =    Set Variable    ${length_of_text}.txt
    ${length_of_text} =    Convert To Integer    ${length_of_text}
    ${text} =    Generate Random String    length=${length_of_text}
    OperatingSystem.Create File    ${CURDIR}/${filename}    ${text}
    RETURN    ${filename}

When called with a large input like:

${file_name} =    Generate Test Text File    ${10 000 000}

The Generate Random String keyword was taking almost 10 seconds. The solution was to use Python's built-in functions and proper path handling:

Generate Test Text File
    [Arguments]    ${length_of_text}
    ${filename} =    Set Variable    ${length_of_text}.txt
    ${length_of_text} =    Convert To Integer    ${length_of_text}
    ${full_path} =    Normalize Path    ${CURDIR}${/}${filename}
    Evaluate    open(r'${full_path}', 'w').write(''.join(random.choices(string.ascii_letters + string.digits, k=${length_of_text})))    random,string
    RETURN    ${filename}

Key improvements:

2. Browser Server Launch Optimization

The original implementation used a static sleep:

Launch Browser Server Via CLI
    ${python} =    Get Python Binary Path
    ${process1} =    Start Process
    ...    ${python}
    ...    -m
    ...    Browser.entry
    ...    launch-browser-server
    ...    chromium
    ...    headless\=${HEADLESS}
    ...    port\=8277
    ...    wsPath\=server2
    ${process2} =    Start Process
    ...    ${python}
    ...    -m
    ...    Browser.entry
    ...    launch-browser-server
    ...    chromium
    ...    headless\=${HEADLESS}
    ...    port\=8273
    ...    wsPath\=server3
    Sleep    10s
    Connect To Browser    wsEndpoint=ws://localhost:8277/server2    browser=chromium
    # ... rest of the test

The improved version replaces the static sleep with dynamic waiting:

Launch Browser Server Via CLI
    ${python} =    Get Python Binary Path
    ${process1} =    Start Process
    ...    ${python}
    ...    -m
    ...    Browser.entry
    ...    launch-browser-server
    ...    chromium
    ...    headless\=${HEADLESS}
    ...    port\=8277
    ...    wsPath\=server2
    ${process2} =    Start Process
    ...    ${python}
    ...    -m
    ...    Browser.entry
    ...    launch-browser-server
    ...    chromium
    ...    headless\=${HEADLESS}
    ...    port\=8273
    ...    wsPath\=server3
    Wait Until Keyword Succeeds
    ...    10s
    ...    1s
    ...    Connect To Browser
    ...    wsEndpoint=ws://localhost:8277/server2
    ...    browser=chromium
    # ... rest of the test

Key improvements:

Value of Timing Statistics

The timing statistics feature in rflogs.io provides several key benefits:

  1. Clear visibility into where test execution time is spent
  2. Identification of both frequent slow operations and one-off bottlenecks
  3. Ability to validate optimization impacts
  4. Easy sharing of performance data with team members

You can try this right now on your own test runs. Just upload your run information to rflogs.io and start exploring. The timing statistics will help you identify the most impactful optimization opportunities in your test suite.