I'm new to Selenium, and also fuzz testing. I see that Selenium IDE only allows the fixed test cases. But then fuzz testing seems to be helpful.
So what's behind a fuzz testing, what kind of tests does Selenium offer, is this a black box or white box testing.
Any help would be appreciated.
For a short answer:
Selenium is mostly about black-box testing, but you could do some whiter testing also with Selenium.
Selenium RC gives you much more freedom to do fuzz testing than Selenium IDE.
For a long answer, see below:
In this post I would try to explain the concept of randomly testing your web application using Selenium RC.
Normally speaking, a black-box testing technique like Selenium gives you a good freedom to
(1) Enter any value to a certain field
(2) Choose any field to test in a certain HTML form
(3) Choose any execution order/step to test a certain set of fields.
Basically you
use (1) to test a specific field in your HTML form (did you choose a good maximum length for a field), your JavaScript handling of that field's value (e.g. turning "t" into today's date, turning "+1" into tomorrow's date), and your back end Database's handling of that variable (VARCHAR length, conversion of numerical string into numerical value, ...).
use (2) to test ALL possible fields
use (3) to test the interaction of the fields with each other: is there a JavaScript alert popped up if the username field was not entered before the password field, is there a database (e.g. Oracle) trigger "popped up" when certain condition is not met.
Note that testing EVERYTHING (all states of your program, constructed by possible combinations of all variables) is not possible even in theory (e.g.: consider testing your small function used to parse a string, then how many possible values does a string have ?). Therefore, in reality, given a limited resource (time, money, people) you want to test only the "most crucial" execution paths of your web application. A path is called more "crucial" if it has more of the properties: (a) is executed frequently, (b) a deviation from specification causes serious loss.
Unfortunately, it is hard to know which execution cases are crucial, unless you have recorded all use cases of your application and select the most frequent ones, which is a very time consuming process. Furthermore even some bugs at the least executed use case could cause a lot of trouble if it is a security hole (e.g. someone steals all customers' password given a tiny bug in an URL handling of some PHP page).
That is why you need to randomly scan the testing space (i.e. the space of values used in those use cases), with the hope to run-something-and-scan-everything. This is called fuzz testing.
Using Selenium RC you could easily do all the phases (1), (2) and (3): testing any value in any field under any execution step by doing some programming in a supported language like Java, PHP, CSharp, Ruby, Perl, Python.
Following is the steps to do all these phases (1), (2) and (3):
Create list of your HTML fields so that you could easily iterate through them. If your HTML fields are not structurized enough (legacy reason), think of adding a new attribute that contains a specific id, e.g. selenium-id to your HTML element, to (1) simplify XPath formation, (2) speed up XPath resolution and (3) to avoid translation hassle. While choosing the value for these newly added selenium-id, you are free to help iterating while fuzzing by (a) using consecutive numbers, (b) using names that forms a consistency.
Create a random variable to control the step, say rand_step
Create a random variable to control the field, say rand_field
Eventually, create a random variable to control the value entered into a certain field, say rand_value.
Now, inside your fuzzing algorithm, iterate first through the values of rand_step, then with each such iteration, iterate through rand_field, then finally iterate through rand_value.
That said, fuzz testing helps to scan your whole application's use case values space after a limited execution time. It is said that "a plague of new vulnerabilities emerge that affected popular client-side applications including Microsoft Internet Explorer, Microsoft Word and Microsoft Excel; a large portion of these vulnerabilities were discovered through fuzzing"
But fuzz testing does not come without drawback. One if which is the ability to reproduce a test case given all those randomness. But you could easily overcome this limitation by either doing one of the following:
Generating the test cases before hand in a batch file to be used in a certain period of time, and apply this file gradually
Generating the test cases on the fly, together with logging down those cases
Logging down only the failed cases.
To answer more on if Selenium is black or white box.
Definitions about black-box and white-box
Black box: checks if one box (usually the whole app) delivers the correct outputs while being fed with inputs. Theoretically, your application is bug free if ALL possible input-output pairs are verified.
White box: checks the control flow of the source. Theoretically, your application is bug free if ALL execution paths are visited without problem.
But in real life, you cannot do ALL input-output pairs, nor ALL execution paths, because you always have limited resources in
Time
Money
People
With selenium: you mimic the user by entering a value or do a certain click on a web application, and you wait if the browser gives you the behavior you want. You don't know and don't care how the inner functionality of the web application actually work. That's why a typical Selenium testing is black-box testing
Related
I was wondering if testing web application based on comparing images of a screenshot is used in the industry and if it's a good approach.
Scenario:
- model image is taken by hand
- test compares only selected parts of an image
- test is written in selenium for example
- test has always the same data to work on
- test is always running on the same screen (the same resolution)
- test will compare images after some steps (for example: if the user account page looks good after registration - we have always the same data for test)
Does this have some advantages?
Is it a 'stable' approach to testing web apps?
Could it be useful as the last step of (for example) selenium test to verify the results?
What do you think about it?
I did a search for that topic but couldn't find any good resources.
There are solutions for this kind of testing, for example, there is Applitools.
It is based on taking a baseline screenshot, and then the subsequent screenshots take the diff from the original image. There are 4 different comparison levels:
Exact (MatchLevel.EXACT) - pixel-to-pixel comparison
Strict (MatchLevel.STRICT) - Strict compares everything including content (text), fonts, layout, colors and position of each of the elements but knows to ignore rendering changes that are not visible to the human
Content (MatchLevel.CONTENT) - Content works in a similar way to Strict except for the fact that it ignores colors
Layout (MatchLevel.LAYOUT) - compares the layouts (i.e. structure) of the baseline and actual images. It ignores the content, color and other style changes between the pages.
A big advantage, in my opinion, is that this kind of testing can catch unexpected bugs (visual or otherwise) and in one go (you don't need to write multiple assertions, you just compare screenshots). You can write scripts with less code, as well.
Possible downsides are: you cannot handle dynamic content, sometimes it is impossible to take a screenshot and, since there are screenshots, test execution (working with img files) can be longer.
NOTE: I'm not involved with Applitools, but they have a site with many tutorial courses.
Is it possible for a program cannot find the failure by using dynamic testing, but have fault? any simple example?
Please help! thanks.
Yes. Testing can only prove the absence of bugs for what you tested. Dynamic testing cannot cover all possible inputs and outputs in all environments with all dependencies.
First is to simply not test the code in question. This can be verified by checking the coverage of your test. Even if you achieve 100% coverage there can still be flaws.
Next is to not check all possible types and ranges of inputs. For example, if you have a function that scans for a word in a string, you need to check for...
The word at the start of the string.
The word at the end of the string.
The word in the middle of the string.
A string without the word.
The empty string.
These are known as boundary conditions and include things like:
0
Negative numbers
Empty strings
Null
Extremely large values
Decimals
Unicode
Empty files
Extremely large files
If the code in question keeps state, maybe in an object, maybe in global variables, you have to test that state does not become corrupted or interfere with subsequent runs.
If you're doing parallel processing you must test any number of possibilities for deadlocks or corruption resulting from trying to do the same thing at the same time. For example, two processes trying to write to the same file. Or two processes both waiting for a lock on the same resource. Do they lock only what they need? Do they give up their locks ASAP?
Once you test all the ways the code is supposed to work, you have to test all the ways that it can fail, whether it fails gracefully with an exception (instead of garbage), whether an error leaves it in a corrupted state, and so on. How does it handle resource failure, like failing to connect to a database? This becomes particularly important working with databases and files to ensure a failure doesn't leave things partially altered.
For example, if you're transferring money from one account to another you might write:
my $from_balance = get_balance($from);
my $to_balance = get_balance($to);
set_balance($from, $from_balance - $amount);
set_balance($to, $to_balance + $amount);
What happens if the program crashes after the first set_balance? What happens if another process changes either balance between get_balance and set_balance? These sorts of concurrency issues must be thought of and tested.
There's all the different environments the code could run in. Different operating systems. Different compilers. Different dependencies. Different databases. And all with different versions. All these have to be tested.
The test can simply be wrong. It can be a mistake in the test. It can be a mistake in the spec. Generally one tests the same code in different ways to avoid this problem.
The test can be right, the spec can be right, but the feature is wrong. It could be a bad design. It could be a bad idea. You can argue this isn't a "bug", but if the users don't like it, it needs to be fixed.
If your testing makes use of a lot of mocking, your mocks may not reflect how thing thing being mocked actually behaves.
And so on.
For all these flaws, dynamic testing remains the best we've got for testing more than a few dozen lines of code.
Lately I need to do an impact analysis on changing a DB column definition of a widely used table (like PRODUCT, USER, etc). I find it is a very time consuming, boring and difficult task. I would like to ask if there is any known methodology to do so?
The question also apply to changes on application, file system, search engine, etc. At first, I thought this kind of functional relationship should be pre-documented or some how keep tracked, but then I realize that everything can have changes, it would be impossible to do so.
I don't even know what should be tagged to this question, please help.
Sorry for my poor English.
Sure. One can technically at least know what code touches the DB column (reads or writes it), by determining program slices.
Methodology: Find all SQL code elements in your sources. Determine which ones touch the column in question. (Careful: SELECT ALL may touch your column, so you need to know the schema). Determine which variables read or write that column. Follow those variables wherever they go, and determine the code and variables they affect; follow all those variables too. (This amounts to computing a forward slice). Likewise, find the sources of the variables used to fill the column; follow them back to their code and sources, and follow those variables too. (This amounts to computing a backward slice).
All the elements of the slice are potentially affecting/affected by a change. There may be conditions in the slice-selected code that are clearly outside the conditions expected by your new use case, and you can eliminate that code from consideration. Everything else in the slices you may have inspect/modify to make your change.
Now, your change may affect some other code (e.g., a new place to use the DB column, or combine the value from the DB column with some other value). You'll want to inspect up and downstream slices on the code you change too.
You can apply this process for any change you might make to the code base, not just DB columns.
Manually this is not easy to do in a big code base, and it certainly isn't quick. There is some automation to do for C and C++ code, but not much for other languages.
You can get a bad approximation by running test cases that involve you desired variable or action, and inspecting the test coverage. (Your approximation gets better if you run test cases you are sure does NOT cover your desired variable or action, and eliminating all the code it covers).
Eventually this task cannot be automated or reduced to an algorithm, otherwise there would be a tool to preview refactored changes. The better you wrote code in the beginning, the easier the task.
Let me explain how to reach the answer: isolation is the key. Mapping everything to object properties can help you automate your review.
I can give you an example. If you can manage to map your specific case to the below, it will save your life.
The OR/M change pattern
Like Hibernate or Entity Framework...
A change to a database column may be simply previewed by analysing what code uses a certain object's property. Since all DB columns are mapped to object properties, and assuming no code uses pure SQL, you are good to go for your estimations
This is a very simple pattern for change management.
In order to reduce a file system/network or data file issue to the above pattern you need other software patterns implemented. I mean, if you can reduce a complex scenario to a change in your objects' properties, you can leverage your IDE to detect the changes for you, including code that needs a slight modification to compile or needs to be rewritten at all.
If you want to manage a change in a remote service when you initially write your software, wrap that service in an interface. So you will only have to modify its implementation
If you want to manage a possible change in a data file format (e.g. length of field change in positional format, column reordering), write a service that maps that file to object (like using BeanIO parser)
If you want to manage a possible change in file system paths, design your application to use more runtime variables
If you want to manage a possible change in cryptography algorithms, wrap them in services (e.g. HashService, CryptoService, SignService)
If you do the above, your manual requirements review will be easier. Because the overall task is manual, but can be aided with automated tools. You can try to change the name of a class's property and see its side effects in the compiler
Worst case
Obviously if you need to change the name, type and length of a specific column in a database in a software with plain SQL hardcoded and shattered in multiple places around the code, and worse many tables present similar column namings, plus without project documentation (did I write worst case, right?) of a total of 10000+ classes, you have no other way than manually exploring your project, using find tools but not relying on them.
And if you don't have a test plan, which is the document from which you can hope to originate a software test suite, it will be time to make one.
Just adding my 2 cents. I'm assuming you're working in a production environment so there's got to be some form of unit tests, integration tests and system tests already written.
If yes, then a good way to validate your changes is to run all these tests again and create any new tests which might be necessary.
And to state the obvious, do not integrate your code changes into the main production code base without running these tests.
Yet again changes which worked fine in a test environment may not work in a production environment.
Have some form of source code configuration management system like Subversion, GitHub, CVS etc.
This enables you to roll back your changes
I have several tests to run and all of them share a certain number x of initial actions (say login, fill form fields, click buttons, etc.), then they diverge.
Is it possible to let the browser execute the first x actions just once, save the current state and then execute all the test separately (in parallel if possible), each one with a separate browser instance?
Thanks
You should try to avoid duplicating effort in your tests. However, you must aim for consistency above all, and maintainability is probably just as important.
What that means is that using the browser in a way a real user wouldn't (I think your state-saving idea counts) is very risky for consistency, and may fail to give you the meaningful results you need.
Another alternative - a 'monolithic' test that attempts to cover multiple scenarios within one user session - is also problematic, because it's slower to run and slower to write and debug.
To be honest I think the idea of "browser state" is one that isn't a good fit for the real web.
My suggestion is to run dedicated, self-contained, clean tests - even if they do duplicate things like login/registration forms. However, if it is important to minimise the length of your test runs, try running them in parallel: ideally on multiple VMs, or via Selenium Grid.
We have the following UI as shown in the image. These parameters are cascaded i.e they are inter-dependent. If you select continent then respective countries will come and then when you select country respective city will come.
I want to automate testing of each option. This was just a dummy UI. In my case these fields are dynamic i.e generated on the fly through shell/groovy scripts and I have more than 10 such fields.
I have seen Robot Framework and Job-DSL Plugin but I am not able to write test cases for these option selection. Also I have seen some tools which record your steps and generate a test file according to steps performed based on option selected and buttons clicked?
Can some one guide me for the optimum tool or platform so as to do Automation testing?
It's hard to say what is 'the optimal way' but here's what I would do:
I assume that all selections are based on the Jenkins jelly calling a method in your code, I suggest you put the effort in combining these calls in a normal unit test first. There you can try all possibilities in a much faster way.
Then when it comes to real UI test, record a Selenium session and translate that into the source code of your choice.