I'm trying to make some tests on a JavaScript application and someone advised me to use Selenium. I visited its site but I cannot understand what is it and how can I use it for testing. Can someone help me understand?
There are a lot of options and it can be quite daunting to start.
Start with the IDE. It is a Firefox plug-in and would get you writing tests in no time. This is good for semi-automated tests running only on Firefox. And good to get some scripts generated for you to kick-start your tests.
Setup RC. It is a Java program that runs on 'a' box (could be localhost) spawning browsers and running your tests and you can connect to it using variety of languages and program your tests. RC is your friend if you want to automate your testing completely.
As for Grid, it is yet another Java program that manages different RCs on your network which makes it all distributed from browser, load and functionality perspectives. You don't need this initially and when the time comes your work on RC would be reusable 80-100%.
If you're using the Firefox plugin, all you have to do is record a "test". Then generate the testing code in the language you want to run the scripts in. They have an option for Java - and the test can be run standalone (outside of a browser on any platform). The test will attempt to replicate what you did in the browser. If it is able to complete the same steps, your test passes.
Selenium replicates what the browser does when running it's tests and does an admirable job (though not perfect)
Related
Is there a way to write integration tests for WebExtension based Browser addons?
In addition to unit tests, I would like to write an integration test that fully loads an extension, performs some tests, and finally unloads it.
My own research:
I assume it is possible with Selenium, but from my experience Selenium can lead to flakey tests that are hard to maintain. I wonder if there is a lighter alternative. Could also be that Selenium is the tool of choice. I have to admit that I don't have much experience with testing Browser extensions.
For limited use cases, I have used mock-browser. But as far as I understand it, it is not possible to simulate loading and unloading extensions with it.
Example:
To get an idea what kind of tests I would like to automate, here is a small example of a manual test that we have:
Start a browser with the extension. If the extension loads correctly, it will start increase a counter periodically
(Manually) check whether the counter increases. If the counter increases, the test passes.
If the test environment support loading an extension, this manual test could be easily automated. The problem is just to setup an environment that allows to load the extension. Currently, we run our unit tests with Node and using Mocha as a test framework.
There are a lot of questions on SO about how to debug a standalone piece of Javascript - that isn't what I want. None of the previous Eclipse/javascript questions seem to be on point, which surprised me.
I am using Eclipse for Java EE (Neon, the latest version) to develop a JSP/servlet website - a full website, not just javascript, and not just java/jsp - everything together. I can compile my Java and "debug as" on an instance of Tomcat spawned by Eclipse, and the web pages show up inside of a window in Eclipse. I can set and hit Java breakpoints all day long while using "debug as" - but setting breakpoints in javascript doesn't do diddly squat. I've been having to run a standalone instance of Tomcat, deploy war files to it, wait for the war files to decompress, then debug my Javascript inside of Firefox. This is particularly annoying because I'm relatively new to javascript and am doing some complex things on the page (and truth be told, making some silly mistakes a compiler in a typed language would catch for me before letting me waste my time trying to run the code) and the "change, watch Eclipse chew deploying war, wait for Tomcat to chew uncompressing the war, test" cycle is just unacceptably long.
Isn't there an easier way to debug BOTH java and javascript from the same IDE without having to export and deploy WAR files? Is there is a setting I can toggle or something I can install in Eclipse to make it an all-in-one IDE? Ideally I would like to be able to step through, for example, an AJAX call into my servlet AND watch what happens in the javascript after it returns - within the same debugging session - so let me preemptively state that copying the changed js file(s) directly to the decompressed folder in tomcat/webapps as a faster way to continue to do split debugging is not the kind of "workaround answer" I'm looking for.
JavaScript debugging is going to be supported in Eclipse Neon 1 release (September 2016). Here is a demo video in which step-by-step process of debugging both front-end and back-end is explained - https://youtu.be/7oQz1Ja1H08 .
Basically, running Chrome / Chromium with extra parameters and tuning source mapping manually is not really user-friendly now, but we are going to improve it for Neon 1 and future releases.
Contributions of any kind are most welcome ;)
I'm going to write bunch of browser extensions (the same functionality for each popular browser). I hope, that some of the code will be shared, but I'm not sure about this yet. For sure some of extensions will use native API. I have not much experience with TDD/BDD, and I thought it's good time to start folowing these ideas from this project.
The problem is, I have no idea how to handle it. Should I write different tests for each browser? How far should I go with these tests? These extensions will be quite simple - some data in a local storage, refreshing a page and listening through web sockets.
And my observation about why is it hard for me - because there is a lot of behaviour, and not so much models, which are also dependent on a platform.
I practise two different ways of testing my browser extensions:
Unit tests
Integration test
Introduction
I will use the cross-browser YouTube Lyrics by Rob W extension as an example throughout this answer. The core of this extension is written in JavaScript and organized with AMD modules. A build script generates the extension files for each browser. With r.js, I streamline the inclusion of browser-specific modules, such as the one for cross-origin HTTP requests and persistent storage (for preferences), and a module with tons of polyfills for IE.
The extension inserts a panel with lyrics for the currently played song on YouTube, Grooveshark and Spotify. I have no control over these third-party sites, so I need an automated way to verify that the extension still works well.
Workflow
During development:
Implement / edit feature, and write a unit test if the feature is not trivial.
Run all unit tests to see if anything broke. If anything is wrong, go back to 1.
Commit to git.
Before release:
Run all unit tests to verify that the individual modules is still working.
Run all integration tests to verify that the extension as whole is still working.
Bump versions, build extensions.
Upload update to the official extension galleries and my website (Safari and IE extensions have to be hosted by yourself) and commit to git.
Unit testing
I use mocha + expect.js to write tests. I don't test every method for each module, just the ones that matter. For instance:
The DOM parsing method. Most DOM parsing methods in the wild (including jQuery) are flawed: Any external resources are loaded and JavaScript is executed.
I verify that the DOM parsing method correctly parses DOM without negative side effects.
The preference module: I verify that data can be saved and returned.
My extension fetches lyrics from external sources. These sources are defined in separate modules. These definitions are recognized and used by the InfoProvider module, which takes a query, (black box), and outputs the search results.
First I test whether the InfoProvider module functions correctly.
Then, for each of the 17 sources, I pass a pre-defined query to the source (with InfoProvider) and verify that the results are expected:
The query succeeds
The returned song title matches (by applying a word similarity algorithm)
The length of the returned lyrics fall inside the expected range.
Whether the UI is not obviously broken, e.g. by clicking on the Close button.
These tests can be run directly from a local server, or within a browser extension. The advantage of the local server is that you can edit the test and refresh the browser to see the results. If all of these tests pass, I run the tests from the browser extension.
By passing an extra parameter debug to my build script, the unit tests are bundled with my extension.
Running the tests within a web page is not sufficient, because the extension's environment may differ from the normal page. For instance, in an Opera 12 extension, there's no global location object.
Remark: I don't include the tests in the release build. Most users don't take the efforts to report and investigate bugs, they will just give a low rating and say something like "Doesn't work". Make sure that your extension functions without obvious bugs before shipping it.
Summary
View modules as black boxes. You don't care what's inside, as long as the output matches is expected or a given input.
Start with testing the critical parts of your extension.
Make sure that the tests can be build and run easily, possibly in a non-extension environment.
Don't forget to run the tests within the extension's execution context, to ensure that there's no constraint or unexpected condition inside the extension's context which break your code.
Integration testing
I use Selenium 2 to test whether my extension still works on YouTube, Grooveshark (3x) and Spotify.
Initially, I just used the Selenium IDE to record tests and see if it worked. That went well, until I needed more flexibility: I wanted to conditionally run a test depending on whether the test account was logged in or not. That's not possible with the default Selenium IDE (it's said to be possible with the FlowControl plugin - I haven't tried).
The Selenium IDE offers an option to export the existing tests in other formats, including JUnit 4 tests (Java). Unfortunately, this result wasn't satisfying. Many commands were not recognized.
So, I abandoned the Selenium IDE, and switched to Selenium.
Note that when you search for "Selenium", you will find information about Selenium RC (Selenium 1) and Selenium WebDriver (Selenium 2). The first is the old and deprecated, the latter (Selenium WebDriver) should be used for new projects.
Once you discovered how the documentation works, it's quite easy to use.
I prefer the documentation at the project page, because it's generally concise (the wiki) and complete (the Java docs).
If you want to get started quickly, read the Getting Started wiki page. If you've got spare time, look through the documentation at SeleniumHQ, in particular the Selenium WebDriver and WebDriver: Advanced Usage.
Selenium Grid is also worth reading. This feature allows you to distribute tests across different (virtual) machines. Great if you want to test your extension in IE8, 9 and 10, simultaneously (to run multiple versions of Internet Explorer, you need virtualization).
Automating tests is nice. What's more nice? Automating installation of extensions!
The ChromeDriver and FirefoxDriver support the installation of extensions, as seen in this example.
For the SafariDriver, I've written two classes to install a custom Safari extension. I've published it and sent in a PR to Selenium, so it might be available to everyone in the future: https://github.com/SeleniumHQ/selenium/pull/87
The OperaDriver does not support installation of custom extensions (technically, it should be possible though).
Note that with the advent of Chromium-powered Opera, the old OperaDriver doesn't work any more.
There's an Internet Explorer Driver, and this one does definitely not allow one to install a custom extension. Internet Explorer doesn't have built-in support for extensions. Extensions are installed through MSI or EXE installers, which are not even integrated in Internet Explorer. So, in order to automatically install your extension in IE, you need to be able to silently run an installer which installs your IE plugin. I haven't tried this yet.
Testing browser extensions posed some difficulty for me as well, but I've settled on implementing tests in a few different areas that I can invoke simultaneously from browsers driven by Selenium.
The steps I use are:
First, I write test code integrated into the extension code that can be activated by simply going to a specific URL. When the extension sees that URL, it begins running the tests.
Then, in the page that activates the testing in the extension I execute server-side tests to be sure the API performs, and record and log issues there. I record the methods invoked, the time they took, and any errors. So I can see the method the extension invoked, the web performance, the business logic performance, and the database performance.
Lastly, I automatically invoke browsers to point at that specific URL and record their performance along with other test information, errors, etc on any given client system using Selenium:
http://docs.seleniumhq.org/
This way I can break down the tests in terms of browser, extension, server, application, and database and link them all together according to specific test sets. It takes a bit of work to put it all together, but once its done you can have a very nice extension testing framework.
Typically for cross-browser extension development in order to maintain a single code-base I use crossrider, but you can do this with any framework or with native extensions as you wish, Selenium won't care, it is just driving the extension to a particular page and allowing you to interact and perform tests.
One nice thing about this approach is you can use it for live users as well. If you are providing support for your extension, have a user go to your test url and immediately you will see the extension and server-side performance. You won't get the Selenium tests of course, but you will capture a lot of issues this way - very useful when you are coding against a variety of browsers and browser versions.
I want to run UI tests using browserfarms like BrowserStack. We are currently using BS to run Unit tests via JsTestDriver. So starting the server, letting a bunch of browsers created by the browserfarm connect to the jstd server and then execute the tests.
Unfortunately, I wasn't able to find a way to write UI tests that work with jstd (click some button, type something, etc).
Selenium RC is a framework that aims to UI tests, however it forces to use own browser instances: Selenium starts its own browsers via Drivers that are part of the framework.
What I want is to combine the JsTestDriver concept with the UI testing of Selenium: write tests with Selenium, start the Selenium RC server on a localhost, let a bunch of browser connect to the server that were started on a browserfarm and then execute the UI tests.
Is this even possible? Is there another way to run UI tests with JSTD? Is Selenium RC not capable of capturing browsers that are not started using a webdriver?
thanks in advance.
Technically yes, but it's gonna hurt.
Since jsTestDriver supports asynchronous tests, you can start (and connect to it) a browser (using JavaScript) in the setup stage.
"Is Selenium RC not capable of capturing browsers that are not started using a webdriver?"
Probably not in the near future.
I'm pretty new to workign with Javascript.
In most languages you can run the code quickly locally on your machine. From what I've seen, in JS you generally only use it via the browser, and so I've been uploading my code an viewing its effects in the browser. This has proven very tiresome. Also, if I mak one error, it seems like my JS/JQuery will just do NOTHING, instead of giving me a useful error, message, which is making it painfully slow to code in.
IS there some way to run JS locally to see that it is working as I go? And then only upload it to the web when I'm mostly done? What ways are there for me to do this? What ways aer there for me to unit test the Javascript locally? Say I have some JAML that should render as <p>HI</p>, how do I run this locally in a unit test?
Thanks for the help,
Alex
EDIT:
Thanks for all the great suggestions. I'll have to take a bit of time and go through them to see which ones best help me in my situation.
Since you're using jQuery, I assume that you actually want to manipulate the various elements on your page. So depending on your specific development enviroment, uploading it each time is probably the way to go anyway. If you can set up a dev enviroment on your local machine (not always possible) then go with that.
As an actual answer to your question, I suggest using Chrome's developer tools, it doesn't just have the console, but an element inspector, and a resource tracker (resource tracker is invaluable when working with JSON and AJAX, since invalid json will fail silently)
As far as I know, the firebug plugin for firefox (dont use it myself) has a similar feature set, so if you're more comfortable with that go with it.
Just remember, as a developer, your development (and debuggin) enviroment is just as important as the code that you are writing.
EDIT: Noticed that you mentioned unit testing. There are several unit testing frameworks out there for JS including one that integrates with firebug called FireUnit. Do a quick google search to find more if you want.
You don't need to upload the JS file to a server to test it. Just write an html and declare the js binding
<script
src="js/yourJSFile.js"
type="text/javascript"></script>
Edit the JS file in your favorite editor and then refresh the page to test it.
For unit testing the best option is Selenium. It allows you to record an interaction with the browser and then play it back.
You can use Firebug with Firefox to debug JS, and Google Chrome has a debugger built-in (use the Tools -> Developer Tools menu).
You can run Javascript from the local file on your machine in your browser, so you can skip the uploading step.
Also, I'd recommend using Firefox/Firebug combo for developing Javascript as it will be very handy, especially for the part you mentioned about not seeing what's going wrong with your code.
Even if you upload your javascript it gets downloaded back to you as soon as you visit the webpage that invoques it. Its run client side always. So stick to local and use firebug as the others have said. Google`s developer tool is quite nice too.
In the browser if you open the developer tools, follow the following steps:
1) Navigate to sources
2) Under sources, click snippet and open run.js
3) You can use run.js to write as much code as you want and run it locally only to see if your code is working or not (it will give you output on the console)
4) Also you can get used to some keyboard shortcuts to make it faster for you.
5) For small javascript codes, you can navigate to console and run your code there
If you want to do unit testing with Javascript there are extension of Firebug that can help you with that. I haven't try any of them, so I can't really tell you which one are worth considering, but you can easily find them if you search for the keyword "Firebug unit testing" on Google.
What seems to be comming on top is FireUnit. You can find some information about how it works here.
Consider Spider Monkey, which is a javascript engine separate from a browser. If what you are developing does not involve rendering to a webpage or can be separated from the rendering code (good practice!), then this could be useful.
I prefer Chrome to Firefox and I just found Web Server for Chrome.
It's just a Google App that quickly sets up a web server for you and will be set up anywhere you are logged into Chrome. It only allows file access to your current devices, or if you specify, other devices only on the current LAN.
You just point it to the directory with your index.html file and type http://127.0.0.1:8887 in your browser.
Additionally to the answers given you can use Jasmine for automated testing.
A tutorial that seems to help get started with automated testing on Jasmine is provided by Evan Hahn.
I used it and for me it works like a charm. Especially if test driven development is what you are going for!