Robot Framework interview questions
Updated 2026-11-13 · 16 min read
Thirty Robot Framework questions for automation testers, from what keyword-driven testing means to rerunning failures in CI. Every suite on the page was run with Robot Framework 7.5.1 against the free ShopLite app.
Robot Framework turns up in job descriptions at service companies, telecom, embedded and automotive teams, and anywhere testers who do not code every day write automation alongside those who do. Interviewers check three things: that you understand keyword-driven structure, that you can organise a suite so it stays readable, and that you know how to run and debug it in CI.
Every suite below was run with Robot Framework 7.5.1, RequestsLibrary 0.9.7 and SeleniumLibrary 6.9.0 (Python 3.12, headless Chromium in Docker) against the free ShopLite practice app built with BUGS=none. The files sit in one project:
shoplite-robot/
resources/shoplite.resource
libraries/MoneyLibrary.py
tests/products.robot
tests/login_data_driven.robot
tests/control.robot
tests/money.robot
ui/login.robot
The basics
1. What is Robot Framework?
An open-source, generic automation framework written in Python. Tests are written as tables of keywords in plain text files (.robot), and the actual work is done by libraries: SeleniumLibrary or Browser library for web UI, RequestsLibrary for HTTP APIs, AppiumLibrary for mobile, and many more. It produces an HTML log and report after every run. It is also used for robotic process automation (it has a "tasks" mode), not just testing.
2. What does keyword-driven testing mean?
Tests are written as sequences of named actions (keywords) with arguments, such as Login As [email protected] Demo@1234, instead of code. Low-level keywords come from libraries; you combine them into higher-level user keywords that read like business steps. The benefit is readability and reuse; the risk is a huge pile of badly named keywords nobody can find, so keyword design matters.
3. What sections can a .robot file have?
*** Settings *** (libraries, resource files, setups, tags, documentation), *** Variables ***, *** Test Cases *** (or *** Tasks ***), *** Keywords *** (user keywords defined in this file) and *** Comments ***. Only test-case files need test cases; resource files have no test cases. Cells are separated by two or more spaces (or a pipe format); one space is part of the value.
4. What is the difference between a library keyword and a user keyword?
A library keyword is implemented in code (Python, usually) inside a library, for example Click Button from SeleniumLibrary. A user keyword is defined in Robot syntax in a *** Keywords *** section by combining other keywords. Library keywords do the technical work; user keywords describe the business step.
5. Which libraries come with Robot Framework, and which do you install?
Standard libraries ship with it: BuiltIn (always available: Should Be Equal, Log, Evaluate and so on), Collections, String, DateTime, OperatingSystem, Process, XML and a few others. External libraries are installed with pip, for example robotframework-seleniumlibrary, robotframework-browser, robotframework-requests and robotframework-appiumlibrary.
6. What variable types are there?
${scalar} holds one value, @{list} expands a list into separate arguments, &{dict} expands a dictionary into named arguments, and %{ENV_NAME} reads an environment variable. A list or dictionary can also be used as one value with ${name}. Numbers need ${60000} to be a number; plain 60000 is a string.
Likely follow-up: Why does Should Be Equal ${count} 5 fail when count is 5? Because 5 in a cell is the string "5" while ${count} may be an integer. Use Should Be Equal As Integers or write ${5}.
7. What is the VAR syntax, and how is variable scope set?
VAR creates a variable inside a test or keyword and was added in Robot Framework 7.0. By default it is local; scope=TEST, scope=SUITE or scope=GLOBAL widen it. The user guide recommends it over the older Set Test Variable, Set Suite Variable and Set Global Variable keywords on 7.0 and newer. On older projects you will still see those keywords, so know both.
VAR ${total} ${60000}
VAR @{categories} footwear accessories
VAR &{body} [email protected] password=Demo@1234
VAR ${token} abc123 scope=SUITE
8. What is a resource file, and how is it different from a library?
A resource file (.resource) holds shared user keywords and variables written in Robot syntax; test files import it with Resource. A library is code that provides keywords; it is imported with Library. Put business keywords and shared settings in resource files and write a Python library only when Robot syntax becomes awkward.
*** Settings ***
Documentation Keywords shared by the ShopLite API suites.
Library RequestsLibrary
Library Collections
*** Variables ***
${BASE_URL} http://localhost:3001
*** Keywords ***
Open ShopLite API
Create Session shop ${BASE_URL}
POST On Session shop /api/_reset expected_status=204
Login As
[Arguments] ${email} ${password}
VAR &{body} email=${email} password=${password}
${resp}= POST On Session shop /api/auth/login json=${body} expected_status=200
RETURN ${resp.json()}[token]
Auth Header
[Arguments] ${token}
VAR &{headers} Authorization=Bearer ${token}
RETURN ${headers}
9. What are setups and teardowns, and what happens when a suite setup fails?
Suite Setup and Suite Teardown run once around a suite; Test Setup and Test Teardown (or [Setup] and [Teardown] on one test) run around every test. Teardowns run even when the test fails, which is why clean-up belongs there. If a suite setup fails, every test in that suite and its child suites is marked failed without running, and the suite teardown still runs. That is useful to know when a report suddenly shows 200 failures with the same message.
10. How do tags work?
Test Tags in Settings adds tags to every test in the file, [Tags] adds them to one test. You then select tests with --include and --exclude, and the report shows statistics per tag. Common tags: smoke, regression, a module name, a defect id for a known failure. Older files use Force Tags and Default Tags, which are deprecated in recent versions in favour of Test Tags.
11. What files does a run produce?
output.xml (the full machine-readable result), log.html (every keyword, argument and message, for debugging) and report.html (the summary for people). Use --outputdir to put them somewhere tidy, --xunit to add a JUnit-style XML file for CI tools, and rebot to rebuild logs and reports from one or more output.xml files later.
Writing tests
12. Show an API test written with RequestsLibrary.
*** Settings ***
Documentation Product API checks for ShopLite.
Resource ../resources/shoplite.resource
Suite Setup Open ShopLite API
Suite Teardown Delete All Sessions
Test Tags api
*** Test Cases ***
Product List Returns The Requested Page Size
[Tags] smoke
${resp}= GET On Session shop /api/products params=limit=5 expected_status=200
Length Should Be ${resp.json()}[items] 5
Unknown Product Returns 404
${resp}= GET On Session shop /api/products/99999 expected_status=404
Dictionary Should Contain Key ${resp.json()} error
Prices Are Sorted Low To High
${resp}= GET On Session shop /api/products params=sort=price_asc&limit=10
${prices}= Evaluate [p["price"] for p in $resp.json()["items"]]
${sorted}= Evaluate sorted($prices)
Lists Should Be Equal ${prices} ${sorted}
Cart Needs A Token
${resp}= GET On Session shop /api/cart expected_status=401
Should Be Equal ${resp.json()}[error] Authentication required
expected_status makes the keyword fail on any other status. Without it, RequestsLibrary's On Session keywords fail on 4xx and 5xx responses by default; expected_status=any turns that off when you want to assert the status yourself. In Evaluate, $resp (no braces) passes the Python object itself rather than its string form.
13. How do you write a data-driven test?
With a test template: the test cases contain only data rows, and each row calls the template keyword with its columns as arguments.
*** Settings ***
Documentation Data-driven login checks: one keyword, many rows.
Resource ../resources/shoplite.resource
Suite Setup Open ShopLite API
Test Template Login Should Fail With Status
*** Test Cases *** EMAIL PASSWORD STATUS
Wrong Password [email protected] Wrong@1234 401
Unknown Email [email protected] Demo@1234 401
Empty Password [email protected] ${EMPTY} 401
*** Keywords ***
Login Should Fail With Status
[Arguments] ${email} ${password} ${status}
VAR &{body} email=${email} password=${password}
${resp}= POST On Session shop /api/auth/login json=${body} expected_status=any
Should Be Equal As Integers ${resp.status_code} ${status}
Should Not Contain ${resp.text} token
Each row is a separate test in the report, so one bad row does not hide the others. ${EMPTY} is the built-in empty string; an empty cell would shift the columns. For data in CSV or Excel files, teams use an external library such as DataDriver.
14. How do you write a custom keyword in Python?
Write a Python class or module and import it as a library. Method names become keywords (paise_to_rupees becomes Paise To Rupees), or you can name them explicitly with the @keyword decorator.
from robot.api.deco import keyword
class MoneyLibrary:
"""Keywords for amounts that the API returns in paise."""
@keyword("Paise To Rupees")
def paise_to_rupees(self, paise):
paise = int(paise)
return f"₹{paise // 100:,}.{paise % 100:02d}"
*** Settings ***
Library ../libraries/MoneyLibrary.py
*** Test Cases ***
Paise Are Shown As Rupees
${text}= Paise To Rupees 149950
Should Be Equal ${text} ₹1,499.50
Raise an exception (an AssertionError for checks) to fail the keyword; the message appears in the log.
15. Show a browser test with SeleniumLibrary.
*** Settings ***
Documentation Browser checks for the ShopLite login page.
Library SeleniumLibrary
Suite Setup Open Browser ${URL} ${BROWSER} options=${OPTIONS}
Suite Teardown Close All Browsers
Test Setup Go To ${URL}/#/login
*** Variables ***
${URL} http://localhost:3001
${BROWSER} chrome
${OPTIONS} add_argument("--headless=new")
*** Test Cases ***
Demo User Can Log In
Input Text css:[data-testid="login-email"] [email protected]
Input Password css:[data-testid="login-password"] Demo@1234
Click Button css:[data-testid="login-submit"]
Wait Until Element Is Visible css:[data-testid="logout"]
Location Should Contain \#/products
Click Button css:[data-testid="logout"]
Wrong Password Shows An Error
Input Text css:[data-testid="login-email"] [email protected]
Input Password css:[data-testid="login-password"] Wrong@1234
Click Button css:[data-testid="login-submit"]
Wait Until Element Contains css:[data-testid="form-error"] incorrect
Opening the browser once per suite and navigating in Test Setup keeps runs fast. Input Password is like Input Text but does not write the value to the log. In the Docker container used for this page, the options were overridden on the command line to add --no-sandbox and the Chromium binary path; on a normal desktop the default above is enough.
16. Why is there a backslash in \#/products?
Because a cell that starts with # is a comment in Robot syntax. Without the backslash, Location Should Contain #/products passes no argument at all, and the run fails with "expected 1 to 2 arguments, got 0". This exact failure happened while writing this page. Other frequent syntax traps: one space instead of two (the keyword name swallows the argument), forgetting ${} around numbers, and a trailing space in a cell that should be empty.
17. SeleniumLibrary or Browser library?
SeleniumLibrary wraps Selenium WebDriver: long-established, many existing projects, works with Selenium Grid. Browser library wraps Playwright: built-in auto-waiting, browser contexts for isolation, network interception, and it needs Node.js installed alongside Python. For a new project either is defensible; say what you used, why, and what you would check before switching (Grid usage, team skills, existing keywords).
18. How do you handle waits in SeleniumLibrary?
Use the explicit Wait Until ... keywords (Wait Until Element Is Visible, Wait Until Element Contains, Wait Until Page Contains Element), whose time limit comes from Set Selenium Timeout or the library import (timeout=10s). Set Selenium Implicit Wait exists but mixing implicit and explicit waits makes timing unpredictable. Avoid Sleep except for short debugging; it makes suites slow and still flaky. The wait types are compared in implicit vs explicit vs fluent wait.
19. How do loops, conditions and error handling look?
Robot Framework has native FOR, WHILE, IF/ELSE, TRY/EXCEPT and BREAK/CONTINUE, each closed with END.
*** Settings ***
Resource ../resources/shoplite.resource
Suite Setup Open ShopLite API
*** Test Cases ***
Every Category Filter Returns Only That Category
VAR @{categories} footwear accessories
FOR ${category} IN @{categories}
${resp}= GET On Session shop /api/products params=category=${category}
FOR ${product} IN @{resp.json()}[items]
Should Be Equal ${product}[category] ${category}
END
END
Missing Product Is Handled
TRY
GET On Session shop /api/products/99999
EXCEPT HTTPError: 404* type=GLOB
Log Got the expected 404
END
Large Orders Need A Different Payment Method
VAR ${total} ${60000}
IF ${total} > 50000
VAR ${method} upi
ELSE
VAR ${method} cod
END
Should Be Equal ${method} upi
The log of this run shows the EXCEPT branch caught HTTPError: 404 Client Error. Keep logic like this rare in test cases; if a test needs much of it, move it into a keyword or a Python library.
20. Can you write Given/When/Then tests in Robot Framework?
Yes. Robot ignores the prefixes Given, When, Then, And and But when it looks up a keyword, so Given the user is logged in calls a keyword named The User Is Logged In. You get BDD-style readability without a separate Cucumber layer, though without Gherkin feature files or step-definition regexes. See the Cucumber and BDD questions for the Gherkin side.
21. How should you name and organise keywords?
Name keywords for what they achieve in business terms (Add Product To Cart), not for clicks (Click Add Button And Wait). Keep page- or API-specific keywords in their own resource files, keep test files free of locators, and put locators in variables inside the resource that owns that page, the Robot version of the page object model. Document keywords with [Documentation]; the libdoc tool generates HTML docs from libraries and resource files.
Running and CI
22. Which command-line options do you use most?
robot --outputdir results tests # run a folder, write results elsewhere
robot --include smoke tests # only tests tagged smoke
robot --exclude api tests # everything except api
robot --test "Unknown Product*" tests # by test name, wildcards allowed
robot --variable BASE_URL:http://localhost:3001 tests
robot --variablefile env/staging.py tests # many variables at once
robot --dryrun ui # check syntax and keyword names without running
--variable overrides a variable from the command line, which is how one suite runs against several environments. Each of these commands was run for this page against the suites shown (the variable file held one line, BASE_URL = "http://localhost:3001").
23. How do you rerun only the failed tests and combine the results?
Run once, rerun only the failures with --rerunfailed, and merge the two outputs with rebot --merge so the report shows the final state of each test.
robot --outputdir results tests
robot --rerunfailed results/output.xml --output rerun.xml --outputdir results tests
rebot --merge --outputdir results results/output.xml results/rerun.xml
These three commands were run for this page on tests/products.robot, with the first run pointed at a stopped server, so all four product tests failed (the suite setup could not reset the app) and the exit code was 4. The rerun selected those four, they passed, and the merged report showed the final results. Treat a test that passes only on rerun as flaky and track it; reruns are a safety net, not a fix.
24. How do you run Robot tests in parallel?
The core robot command runs tests one after another. The common answer is Pabot (robotframework-pabot), a separate tool that runs suites (or tests) in parallel processes and merges the results. Tests must be independent: separate accounts or data per process, no shared state, no reliance on order.
25. How do you run Robot tests in CI?
Install the pinned dependencies from a requirements.txt, start or point to the application, run robot with --outputdir and --xunit, and always publish log.html, report.html and the xUnit file as artifacts. robot exits with a non-zero code when tests fail, so the pipeline stage fails without extra scripting. See the CI/CD questions for pipeline design in general.
26. What are listeners and pre-run modifiers?
A listener is a Python class or module that Robot calls during the run (when a suite or test starts or ends, when a keyword runs), registered with --listener. Teams use them to push results to dashboards or a test-management tool, or take a screenshot at the end of each failed test. A pre-run modifier (--prerunmodifier) changes the suite before it runs, for example to filter or reorder tests in a custom way.
27. What is a dry run for?
--dryrun parses everything and walks through the tests without running library keywords, catching misspelt keyword names, wrong argument counts and missing imports in seconds. It is a cheap first stage in CI before the real run; it will not catch wrong locators or wrong logic.
Scenarios
28. A Robot suite that ran in 10 minutes now takes an hour. What do you look at?
Open log.html and sort by elapsed time: look for Sleep calls, long waits that always time out before continuing, browsers opened per test instead of per suite, UI steps that could be API calls (log in through the API and set the token instead of typing the password in every test), and suites that are not split for Pabot. Fix the biggest offender first and measure again.
29. Your team wants to move from Robot Framework to pytest or Playwright. What would you consider?
What the current suite does well (readable reports, non-coders contributing), the skills in the team, how much custom Python already exists, CI and reporting integrations, and the cost of migrating a large keyword library. A gradual move, new tests in the new tool and old ones retired as features change, is usually safer than a rewrite. Be balanced; interviewers distrust absolute answers about tools.
30. Explain how you would structure a Robot Framework project for web and API tests.
A tests/ folder split by feature or layer (api/, ui/), a resources/ folder with one resource file per page or API area plus a common file for setup and login, a libraries/ folder for Python keyword code, variables/ files per environment, requirements.txt with pinned versions, and a CI file that runs smoke tests on every change and the full set nightly. Setups create data through the API; teardowns clean it up. Walk through it as you would in explain your automation framework.
Check yourself
- Which variable form reads an environment variable?
- What happens to the tests in a suite whose suite setup fails?
- How do you pass an empty string as a cell value?
- Which option reruns only tests that failed in an earlier run?
- Why did
Location Should Contain #/productsfail with "got 0" arguments?
Answers. (1) %{NAME}. (2) They are all marked failed without running; the suite teardown still runs. (3) ${EMPTY}. (4) --rerunfailed output.xml, then merge with rebot --merge. (5) A cell starting with # is a comment, so the argument disappeared; escape it as \#.
Practise it
Install Robot Framework and RequestsLibrary with pip, start the free ShopLite app, recreate the suites above and run them first with BUGS=none and then with the default build. Add a test for each bug you find, tagged with the area it belongs to.
Quick answers
Is Robot Framework only for Python developers?
No. Tests are written in a keyword syntax that non-programmers can read and write. Python helps when you need custom keywords, and the framework itself runs on Python.
Which library should I use for browser tests in Robot Framework?
SeleniumLibrary (built on Selenium WebDriver) and Browser library (built on Playwright) are the two main choices. Many existing projects use SeleniumLibrary; Browser library has auto-waiting built in. Follow your team's choice.
What version of Robot Framework do the examples use?
Robot Framework 7.5.1 with RequestsLibrary 0.9.7 and SeleniumLibrary 6.9.0 on Python 3.12. The VAR syntax used in the examples needs Robot Framework 7.0 or newer.
Sources
Want a project you can show in interviews?
The portfolio project kit walks you through testing a deliberately buggy app with Selenium or Playwright and API tests, then explaining it. The app itself is free.
