It happens from time to time that an engineer, for some reason, needs to go to a job interview. If that happened to you and you have already gained an experience in test automation, you probably look towards positions like Software Developer in Test or similar. In my opinion, those are one of the most demanding interviews in IT market. How come?
When you are developer, they going to ask you about design patters, object oriented programming, memory management, exception handling, databases, probably something about unit and integration testing, some frameworks details you have experience with, etc. Manual tester is going to answer questions about bug reporting, testing methodologies, documentation, delivery process, tools and others. But when you apply for an automation test engineer job, then… hell yeah – sky is the limit. They can ask you about absolutely every aspect of software development starting from detailed questions about thread management in java, ending with Six Sigma principles. My point is that it’s hard to predict what they are going to ask but at least make sure you are able to express your knowledge gained during test development in your past projects. If you are able to convince interviewer that you have experience in building testing solutions, it won’t matter that you don’t know answers to some other “out of the world” questions.
I would like to present a number of questions that are often asked during interviews and show how I would respond, taking into account java Selenium framework, like the one explained in previous posts.
Object oriented programming features
It is almost certain that you will be asked object oriented programming questions. Try to not give answers from the book, but let your experience talk through you. Here how I would answer question about its features:
During test framework development I was using OO programming features like:
- Encapsulation – It was extremely important to hide WebDriver api calls from java tests layer. Thanks to that it is easy to replace internal implementation without modifying test code. Plus someone who doesn’t know Selenium can understand what is tested inside test method.
- Inheritance – I created abstract class for Page objects, where I implemented some common initialization logic (PageFactory) and added check() method to support fluent api assertions. All Page Objects, which extend that abstract class automatically inherits this logic and can be used in tests.
- Composition – Page Objects consist of fields, which represent business logic on web page. Those fields are in fact WebElements with their very own logic.
- Polymorphism – I was able to build solution which enables running tests for different web browsers, however from test perspective I always use one single method getDriver(), which can have different implementations depending on parameters passed to the framework.
If it comes to good practices in OO programming, it may happen that the will as about SOLID principles as well. Try to find samples from your test framework:
I tried to use SOLID principles in my testing approach in following way:
- Single responsibility – Each field in implemented Page Objects is responsible for communication with single web element and each method is responsible for performing single action on given web element. Every Page Object is responsible for single part of business logic on web gui, etc.
- Open/closed – Let’s assume that new web page is created in the product, similar to already existing one but with some minor differences. I would not try to enhance existing Page Object with additional functionalities, but rather create an abstract class with common parts, from which I could extend.
- Liskov substitution – When I have webpage product with some kind of menu available from every page, then I would try to create some abstract Page with this menu component, to allow all Page Objects to have access to that menu. Now, assuming I have a method which operates on the menu and takes Page as argument, it should always work correctly without knowing exact subtype of Page.
- Interface segregation – Selenium provides nicely grained interfaces to operate on WebDriver, WebElement, etc. It is nice to use, because interfaces exposed to test developers are not overloaded. One of popular testing frameworks, which break this rule, is RestAssured - it exposes huge interface to the client without any segregation.
- Dependency inversion – In all Page Objects in the framework WebDriver is passed as an argument to the constructor. Thanks to that driver implementation can easily be changed in runtime.
Most likely there will also be questions about design patterns. The most frequent question sounds like – What design patterns do you know? Describe one of them.
One of most broadly used design patterns in my test framework is Page Object pattern. It is used in webpage based products testing solutions to separate product business logic from direct interaction with gui. Each Page Object has some portion of gui business logic assigned – fields of PO class represent elements on page and methods encapsulates single actions on those elements. Every public method of the PO returns PO instance, whether itself or any other page.
Another important pattern in scope of my testing framework is Factory, which I am using to produce new instances of WebDriver. Different implementations for different browsers are returned depending on parameter given to a singleton factory class method.
I am also familiar with Strategy design pattern, which separates interface from implementation. I was using this pattern when implementing tests for mobile devices inside of the same framework, which contains desktop tests. Because I separated interfaces and use them in test methods, I was able to create number of implementations for different devices and switch those implementations depending on what is to be tested at the moment.
If you want to use a fatality answer, check Selenium PageFactory internals and how @FindBy works. You will find out Factory, Proxy and Decorator usage. This will give you rank S for the mission.
It is never enough to talk about test pyramid and quite often this subject returns during job interviews. Again, it is important to show that you understand this subject not only from books or trainings. Even if you have 5000 e2e tests, 3 integration tests and 10% unit test coverage in your current project, show that you are aware of the problem.
In my current project we have serious problem with regression testing time. This is because we failed as a team to build our testing solution based on test pyramid. We have large number of end to end tests, while there is almost nothing on integration level. It happened, because created selenium framework was easy to use and too much effort was spent to test new features from gui perspective. There was also a problem in application architecture to extract interfaces, which could be tested on integration level. To fix this we are working with architect and development team to establish such interfaces and start implementing lower level tests. This will help speed up regression and deliver time of new features to production environment.
Selenium and WebDriver
There are some questions related to Selenium and WebDriver, which will tell interviewer almost instantly if you had a chance to work with test framework architecture, or was it only adding new tests to already existing solution.
- What is the difference between Selenium, WebDriver and FirefoxWebDriver?
Selenium is a framework created to support tests for web gui products. WebDriver is a testing api exposed by Selenium from version 2.0, which communicates with browsers via JsonWire protocol. It is also name of main java interface, which provides methods used to interact with browser. FirefoxWebDriver and other drivers implement WebDriver interface and provide support for specific browsers. Starting from Selenium 3.0, implementations of WebDriver are created and hosted by browser providers, so special handling is needed to download and run them.
- What does it mean implicit/explicit wait?
Implicit timeout in WebDriver is a value used when waiting for any element on web page. There is no additional logic needed – when there is a request to web page it simply waits for web element to appear or throws timeout exception if it is not available. It has some default value set at the beginning, but can also be changed in WebDriver api.
On the other side there is explicit timeout, which can be implemented in java to wait for given particular web element. It can be achieved by using WebDriverWait, where timeout value can be provided directly together with other options, like predefined conditions in ExpectedConditions class. Interesting fact is that very often explicit waits use implicit wait indirectly, when querying web page for web elements, so waiting times may not always work as expected.
- What can be done to speed up test execution of selenium tests?
When I was designing my testing solution I kept in mind that it may be required to run tests in parallel in local environment or remotely by using Selenium Grid. To make it possible I carefully created mechanism, which provides separate instance of WebDriver to each test class. Thanks to specific settings in TestNG, automated suite is automatically distributed to threads available in TestNG thread pool. It also works perfectly with Selenium Grid - the only difference is that properly configured RemoteWebDriver needs to be passed to tests.
It would be nice if you could also motivate, why you chose specific test runner, like TestNG or JUnit in your test framework. I use TestNG – let me explain why.
I use TestNG in my testing framework, because it provides nice mechanism for listeners and reporters. Thanks to listeners I can setup special behaviors like add log appender at the beginning of test or take screenshot of application when test fails. By using Reporter I can control when and how test report is generated. It also gives me ability to run my tests in separate threads in various ways. Finally, TestNG has a nice programming api, which can be used to dynamically create suites based on, let’s say, annotations.
Sometimes they want to know why you picked given language to implement your framework. This is my answer:
I’ve chosen java because it is very strict language. Everything must be strictly written and no magical shortcuts are possible. This helps a lot while maintaining test framework, when it is meant to be used by other test developers. Clarity achieved by properly implemented framework in scope of good practices and principles, with support of detailed test coding policies documentation, brings fully unified and standardized tests, whoever writes them. Moreover, test framework written in java benefits from its cross platform nature – it can be run on any operating system with jvm.
While theoretical knowledge taken from books can support you in your working day, it is an experience which matters most to your future employer. Take every opportunity to picture real life situations when answering questions during interview. Preparation to job interview can bring also another unexpected result. When you review your current testing solution and compare it to all good practices, standards and patterns it may happen that you’ll see new opportunities to make it better. Or at least you will know how avoid mistakes you’ve been doing so far, in your new company. ;)
At the end I would like to share the question I was asked during one of QA job interviews. It was fun :) Good luck!
There are 25 mechanical horses and a single racetrack. Each horse completes the track in a pre-programmed time, and the horses all have different finishing times, unknown to you. You can race 5 horses at a time. After a race is over, you get a printout with the order the horses finished, but not the finishing times of the horses. What is the minimum number of races you need to identify the fastest 3 horses?