JavaScript tests and their automation. JavaScript Knowledge Test - Basics Testing javascript code

Code testing is an integral cycle of software development. Beginning development teams often underestimate its role and check the functionality of the application the old fashioned way - “it works, okay.” Sooner or later, this strategy fails and the bug tracker begins to be overwhelmed by a countless army of tasks. To avoid falling into such a trap, I recommend once and for all to understand the nuances of testing JavaScript code.

JavaScript is not the same anymore

Today, JavaScript is more than just a language to spice up the appearance of an application. The times when JavaScript was used for jokes or making menus are irrevocably gone. It is now a standalone language that works equally well on both the client and the server. The role of JavaScript has increased significantly, which means that when writing code you should not be shy about using practices that have proven themselves in other programming languages.

What do I mean by practices and paradigms? Of course, the MVC (model view controller) architectural pattern and code organization patterns. By following these simple tricks, you will be able to write better code that will not only be easy to maintain, but also have the ability to be automatically tested.

Mistake of most testers

It's no secret that the most popular method of testing has always been a banal eye test. Its essence is simple to the point of disgrace - you write a couple of thousand lines of code, solve the problem and launch your creation. I played around, clicked, everything seems to be working, you can upload it to the production server. Everything is extremely simple and with due attention from the developer (ideally a separate person nicknamed “tester”), you can rely on the correct operation of the application.

In practice, everything happens a little differently. As a rule, there is no separate tester. The developer himself tries to check the functionality of the program by performing the sequence of actions specified in the technical specifications. More advanced code forges automate this kind of integration testing using things like Selenium.

Thus, the programmer gets the opportunity to detect only the most serious errors. Unfortunately, “stupid” and “unintended” user actions, as well as cunning moves in business logic, remain behind the scenes in 99% of cases.

The presence of a separate person in the person of a tester also solves the problem partially and up to a certain time. Even if we ignore his sapper's attention to detail, the quality of his testing will tend to zero as the application grows. Let me give you an example from practice.

One day I was assigned to develop a small program. In terms of functionality, the project resembled a simple CRM, which I implemented in the shortest possible time. Having received the due remuneration, I handed over all the sources to the customer and forgot about the project for eight months. Then the fun began. The customer decided to seriously expand the functionality of the program and called me for help. Naturally, I took it and began to sculpt new function after function. At first it was not difficult, but when it came to the overall integration of functionality, a buzzing swarm of bugs rushed in my direction. Pieces of code began to conflict, and we had to spend a lot of time resolving conflicts. “Well, how come you didn’t see that there were problems with your application?” - attentive readers will ask. I launched it, but due to the fact that the application had grown, I simply did not have enough time and nerves to test all the functionality en masse. I limited myself to testing only individual functions and paid handsomely for it. The moral of the story is “Think of testing as an integral part of development.”

Unit tests are like a silver bullet

Unit testing is the best way to save your nerves and increase guarantees of the functionality of individual parts of the application. If you have never come across this terrible word, then I will explain briefly. Unit tests allow you to automate the testing process and test every feature of your application.

After completing the development of a new function (it is possible to write tests before the start of development), the developer writes special code to test his code. In your testing code, you need to simulate different situations and return values. For example, we wrote a function to trim spaces (trim). To test its performance, we must prepare several tests that will allow us to state that:

  • when passing the string "string" we will get "string" as output;
  • when transmitting the terms “line 9”, we will receive “line 9” at the output;
  • We can also add testing for other input parameters (for example, replacing the space character with a tab). In general, the better we cover the code with tests and provide for possible negative options, the greater the chance that at the most crucial moment there will be a little hair left on the head.

    In the JS world, tests are usually written using specialized frameworks. They have everything you need to describe tests, as well as at least some tools for systematizing test progress reports.

    Tests!= extra code

    Developers who don't use unit testing like to argue that unit testing requires writing and maintaining additional code. They say that deadlines in real projects are often tight and it is simply not possible to write additional code.

    I agree about the tight deadlines, but I’m willing to argue about the extra code. On the one hand, yes, tests require additional code, and therefore time to write it. On the other hand, this code acts as an airbag in a car and will definitely pay for itself as the application grows.

    When you don’t have time and are tormented by the desire to give up writing tests, think three times. In this case, it may be more appropriate to cover only the most tricky sections of the code with tests, rather than abandon testing completely. Always think with an eye to the future, as if in a month your program can grow to unprecedented proportions.

    Not every code is tested

    Why do I say that you need to think about testing before writing the main code? Yes, because the code that is initially supposed to be covered by unit tests is written in a slightly different style. Not every code can be tested. Code that mixes logic and representations, and is also crammed into areas where it is impossible to properly test. Here I always advise you to follow a few simple rules:

  • No need to write large functions. Each function should solve one problem, not 100,500 possible situations. For example, there is no need to put the code for sending data to the server into the function responsible for preparing it;
  • A function consisting of more than 10 lines of code is most likely a bad function;
  • Logic and presentation should never go together;
  • QUnit - a classic from the creators of jQuery

    QUnit is especially popular among JavaScript developers. Firstly, it is well documented and easy to use, and secondly, it was created by the authors of jQuery. The library is suitable for testing both jQuery-based and native JavaScript code.

    You can download the latest version of QUnit from the official website - http://qunitjs.com/. The library comes as a single JS and CSS file. Let's assume that you've figured out loading the necessary components, and if so, then it's time to write a trial test. Let's not go far and try to test the above-mentioned trim() function.

    To demonstrate the tests, I created a simple project with the following constructor:

    Index.html – the main file that will display test results; - qunit-1.12.0.js – qunit library file; - example.js – file containing code for testing (in our case, a description of the trim() function); - test.js – file with tests; - qunit-1.12.0.css – styles for designing a report with tests;

    The contents of the index.html and test.js files are presented in Listings 1 and 2. We are most interested in the second listing, which contains the declaration of the function under test (trim()) and the test code to check its functionality. Please note that the trim() function itself can be located anywhere; I put it in the second listing just to save space in the magazine.

    Now let's look at the tests themselves. To check the functionality of our code, the Qunit.js library offers us a number of methods:

  • test() – wrapper for describing the test;
  • ok() – the assertion allows you to check the truth of the first parameter. In our example, I pass it a call to the trim() function we defined and compare it to the value I expect to receive. If the condition is true, the test is passed;
  • equal() – the method allows you to check the equality of the first and second parameters. Please note right away that this method performs a weak check, so it is only suitable for scalar quantities;
  • notEqual() is the opposite of equal(). Executed if the first value is not equal to the second;
  • strictEqual() is similar to equal() with one difference - it uses strict checking (i.e. it also checks the data type);
  • notStrictEqual() – the method is the opposite of strictEqual();
  • deepEqual() – method for recursive assertions, used for primitives, arrays, objects;
  • notDeepEqual() – the method is the opposite of deepEqual();
  • raises() – a statement for testing callback functions that throw an exception;
  • In the second listing, I clearly showed how to apply these methods in practice. If you run the test example in this form, then all tests will pass successfully (see the corresponding figure). To see the difference between tests that passed and those that failed, I slightly modified the code for one test. I deliberately added an erroneous result to the test line using strictEqual() (see the corresponding figure).

    Listing 1. Contents of the index.html file Testing with QUnit Listing 2. Test files and trim() function trim(string) ( return (string || "").replace(/^\s+|\s+$/g, ""); ) test("Test the function trim()", function() ( ok(trim(" test ") == "test", "trim the outer spaces"); ok(trim(" 1 ") == "1", "lots of spaces on the sides"); ok(trim(" 24 ") == "24", "spaces and tabs on the sides"); equal(trim(""), "", "Empty line" "); strictEqual(trim(" ][aker") ));

    We seem to have sorted out testing simple functions. In any case, I have nothing more to add. Next, you need to take real code and try to write tests yourself. Let's look at another frequently encountered task for JavaScript developers - testing asynchronous functions. An application stuffed with JavaScript code interacts 99% with the server side using Ajax. You can't leave this code unchecked either, but writing tests will look a little different. Let's look at an example:

    AsyncTest("myAsyncFunc()", function() ( setTimeout(function() ( ok(myAsyncFunc() == true, "Data transferred successfully"); start(); ), 500); ));

    The main difference between this example and the previous one is that instead of the test() wrapper, asyncTest() is used, thereby directly stating that I am interested in testing specifically asynchronous testing. Next I start the waiting time at 500 ml. sec. During this time, the myAsyncFunc() function should transfer data to the test server, and if all is well, return true. This is where the most interesting moment comes. When asyncTest() is called, the execution thread stops and when the test is completed, it must be launched independently. To control the flow of execution, QUnit has start() and stop() methods.

    Testing asynchronous functions using the QUnit library is quite simple. The last example I would like to look at involves writing a test that performs several asynchronous checks. The main question that arises in such tasks is the optimal place to start the execution thread. The official doc suggests using something like:

    AsyncTest("myAsyncFunc()", function() ( expect(3); //Here we do three checks ok(myAsyncFunc(), "Making the world a better place 1"); ok(myAsyncFunc(), "Making the world a better place 2") ; ok(myAsyncFunc(), "Making the world a better place 3"); setTimeout(function() ( start(); ));

    Test for custom actions

    You should always remember that a lot of interface stuff is written in JavaScript. For example, a user clicks on a pimp and something should happen in response to his click. There is a huge amount of such “interface” code in projects and it also needs to be covered with tests. Let's see how we can simulate a user's keystroke and write a separate test for this action. Let's imagine that we have a certain function that logs the keys pressed. I provided its code in the third listing:

    Listing 3. Logging keystrokes function KeyLogger(target) ( if (!(this instanceof KeyLogger)) ( return new KeyLogger(target); ) this.target = target; this.log = ; var self = this; this.target. off("keydown").on("keydown", function(event) ( self.log.push(event.keyCode); ));

    Now let's try to test this function. First of all, in the body of the test we need to emulate the pressed key. The easiest way to do this is with the jQuery library, which allows you to create an event in a couple of lines of code (see Listing 4).

    Listing 4. Test code for KeyLogger test("Key logging test", function() ( var event, $doc = $(document), keys = KeyLogger($doc); event = $.Event("keydown"); event .keyCode = 9; $doc.trigger(event); equal(keys.log.length, 1, "Key recorded"); equal(keys.log[ 0 ], 9, "Key pressed with code 9"); ));

    At the very beginning of the test listing, I prepare an event to emulate a key press - “keydown”. We will be interested in pressing the Tab key (code 9). Then, using the trigger() method, I send the prepared event, after which I can start testing. First, we check the overall picture - whether a key was pressed, and then its code.

    DOM under the guise of tests

    Since Qunit.js allows you to test user actions, then writing tests for the DOM should not be a problem either. This is indeed true and the example below will confirm my words. I won't comment on it, just look at the code and everything will become clear:

    Test("Add a new div element", function() ( var $fixture = $("#qunit-fixture"); $fixture.append("This is a new div"); equal($("div", $fixture) .length, 1, "New div added successfully!");

    Phantom.JS – running tests from the console

    Writing tests using the Qunit.js library is convenient and simple, but sooner or later you will be struck by the desire to somehow automate the launch of testing and collection of results. For example, for this purpose I have a separate virtual machine in DigitalOcean, which I can only manage using the console.

    The phantom.js project solves this problem quite elegantly. This is not another framework for writing Unit tests, but a full-fledged console version of the WebKit engine. To put it simply, this application emulates a browser. With the help of phantom.js, it is possible not only to automate the verification of test execution, but also to solve many problems that sooner or later arise before a developer: obtaining page rendering results into a file (png, jpg), network monitor functions (loading speed, overall performance, etc.). etc.), emulation of user actions, etc. I recommend that you take the time and read the official documentation on this project; you will definitely find something interesting for yourself.

    Phantom.js can be compiled for different platforms (nix, mac OS X, windows). If you develop everything on Windows, then there are no problems - merge the binaries and go ahead. Minor problems with startup may occur if you have two video adapters installed, one of which is NVidia. In this case, you will have to use the hack described in the sidebar.

    Let's try to get acquainted with phantom.js in practice. To run the tests prepared in the last section through phantom.js and get the execution results into the console, we need a special loader script - run-qunit.js. Open the console (I work on Windows, so I use cmd) and type the command in the format:

    Phantom.exe

    In my case, the launch command looked like this:

    E:\soft\phantomjs>phantomjs.exe E:\temp\testjsforx\qunit\run-qunit.js file:///E: /temp/testjsforx/qunit/index.html The result of its execution: Tests completed in 2592 milliseconds . 9 assertions of 9 passed, 0 failed.

    All tests passed

    It is definitely necessary to cover your code with tests, no matter what scale the application you are creating. Once again, I remind you that even the smallest programs turn into clumsy monsters that need to be supported and added functionality. Well-tested code is the key to success and quality. Yes, it’s not easy to immediately start writing code suitable for automated tests, but believe me, all this torment will more than pay off in the future. That's all for today, good luck!

    When there is no time for tests

    If you don’t have time, there is no point in writing tests for simple functions (take the same trim() from the examples in the article); it is better to focus on the most critical sections of the code. The same rule should be followed when writing frequently changed code. The technical specifications of a live project change frequently, and some functions have to be constantly updated. Such changes can lead to unpleasant moments - the changed code works well with new data, but does not organically digest old data. So, in order not to catch a failure here, it is better to immediately cover such functions with tests. Remember a simple rule - there is no time to cover the entire code with tests, cover the most important part of it.

    Rules for good tests
  • The test should be as simple as possible. The more complex the test, the more likely it is to make mistakes;
  • Tests need to be grouped into modules to make it easier to find errors later and be able to test certain parts of the application;
  • Each test should be independent of other tests;
  • Always write a separate test every time you find bugs;
  • phantom.js problems on Windows

    It just so happened, but I tested all the examples in this article not on Linux, but on good old Windows 7. It turns out that phantom.js has minor problems when working on systems that use several video adapters. On my laptop, in addition to the integrated video chip, there is also NVidia, and because of phantom.js, it categorically refused to respond to the phantom.exit() command. As a result, after executing the script, the phantom.js process did not complete its work and continued to hang in memory. The terminal window also stopped responding to shutdown commands (ctrl + c did not help).

    If you are faced with a similar problem and plan to use phantom.js on Windows, then get ready to do the following hack. Open Nvidia Control Panel. Find the “3D Settings” item in the tree. The “Preferred Graphics Adapter” option should appear on the right side. By default, its value is set to “Auto select”. We need to change it to “High-performance Nvidia processor” or “Integrated graphics hardware”. After this simple trick, phantom.js began to behave obediently.

  • Cristian Johansen's "Test-Driven JavaScript Development" is one of the few books that looks at JavaScript from the point of view of writing tests;
  • John Resing, Beer Bibo “Secrets of the JavaScript Ninja” is a good book that will be useful primarily for JS developers with an average level of training. The book discusses in detail the issues of writing effective cross-browser code, the nuances of event processing and many other goodies.
  • And is the official jQuery testing tool. But QUnit is great for testing any JavaScript code and can even test the JavaScript backend using engines like Rhino or V8.

    If you're not familiar with the idea of ​​"unit testing", don't worry - there's nothing complicated about it:

    "Unit testing or unit testing (English) unit testing) is a process in programming that allows you to check individual modules of a program’s source code for correctness. The idea is to write tests for every non-trivial function or method. This allows you to quickly check whether the next code change has led to regression, that is, to the appearance of errors in already tested places of the program, and also facilitates the detection and elimination of such errors."

    Definition quoted from Wikipedia. Just make tests for each functional block of your code, and if all the tests pass, then you can be sure there are no errors (mainly depends on how carefully the tests are designed).

    Why you should test your code

    If you've never written unit tests before, you've probably just hosted your code directly on a web server, run it, watched for errors, and tried to fix them as they were discovered. This method of working gives rise to many problems.

    Firstly, this is a very tedious and boring activity. Validation is actually quite a difficult job because you have to be sure that everything has been pressed. And in this process there is a very high probability that one or two points may be missed.

    Secondly, everything that is done for such testing cannot be reused. With this method it is very difficult to find regressions. What are regressions? Imagine that you wrote some code and tested it, corrected all the errors you found, and placed the code on the site. The user then sent feedback about new bugs and a request for new features. You go back to the code, fix bugs and add new features. In this case, a situation may arise where old errors appear again, which is called “regression”. You have to check everything again. And there is a chance that you will not find your old mistakes. In any case, it will take time before you realize that the problem is caused by “regression”. When using unit testing, you write a test. Once the code is modified, you filter it through the test again. If regression occurs, then some tests will fail, and you can easily determine which part of the code contains the error. Since you know what you changed, the error will be easy to fix.

    Another advantage of unit testing (especially for web development) is that it is easy to test cross-browser compatibility. You just need to run tests in different browsers. If problems are found in the browser, you can fix them and run the test again. As a result, you will be confident that all target browsers are supported since they have all been tested.

    How to write unit tests in QUnit

    So how do you directly write unit tests in QUnit? The first step is to install the testing environment:

    QUnit Test Suite QUnit Test Suite

    The code that will be tested goes into the myProject.js file, and the tests go into myTests.js. To run the tests, you just need to open the HTML file in your browser. Now it's time to write some test.

    The building block of unit testing is assertion.

    "An assertion is an expression that predicts the return result when your code is executed. If the prediction is incorrect, then the assertion has a value false, which allows us to draw conclusions about the presence of errors."

    To execute assertions, they need to be placed in a test block:

    // test this function function isEven(val) ( return val % 2 === 0; ) test("isEven()", function() ( ok(isEven(0), "Zero is an even number"); ok( isEven(2), "Two is also"); ok(isEven(-4), "And negative four is also an even number"); ok(!isEven(1), "One is an odd number"); isEven(-7), "Like negative seven is an odd number");

    Here we define a function isEven, which checks the parity of a number, and we want to make sure that this function does not return erroneous values.

    First we call the function test(), which builds a test block. The first parameter is the string that will be output as a result. The second parameter is a return function that contains our assertions. This callback function will be called once during QUnit execution.

    We have written five statements, all of which are logical. The logical statement assumes that the first parameter has a value true. The second parameter is the message that is displayed in the result.

    This is what we get after running the test:

    All our statements were successfully confirmed, so we can assume that the function isEven() works as expected.

    Let's see what happens if the statement is false.

    // test this function function isEven(val) ( return val % 2 === 0; ) test("isEven()", function() ( ok(isEven(0), "Zero is an even number"); ok( isEven(2), "Two is also"); ok(isEven(-4), "And negative four is also an even number"); ok(!isEven(1), "One is an odd number"); isEven(-7), "Like negative seven is an odd number"); // Error ok(isEven(3), "Three is an even number");

    And this is what we get as a result of running the test:


    The statement has an error that we made intentionally. But in your project, if some test fails and all other statements are correct, then it will be very easy to find the error.

    Other statements

    ok() is not the only statement that QUnit supports. There are other types of assertions that are convenient to use when writing tests for your projects:

    Comparison Statement

    Comparison Statement equals() assumes that the first parameter (which is the actual value) is equivalent to the second parameter (which is the expected value). This statement is very similar to ok(), but it outputs both real and expected values, which makes debugging the code much easier. As well as ok(), equals() can accept a message for output as a third parameter.

    So instead

    Test("assertions", function() ( ok(1 == 1, "one is equivalent to one"); ))


    Should be used:

    Test("assertions", function() ( equals(1, 1, "one is equivalent to one"); ))


    Note that the expected value is printed at the end of the line.

    And if the values ​​are not equal:

    Test("assertions", function() ( equals(2, 1, "one is equivalent to one"); ))


    This entry gives more information.

    The comparison assertion uses the “==” operator to test parameters, so it cannot work with arrays or objects:

    Test("test", function() ( equals((), (), "error, these are different objects"); equals((a: 1), (a: 1) , "error"); equals(, , "error, these are different arrays"); equals(, , "error");

    For such cases, QUnit has an identity assertion.

    Identity Assertion

    Identity Assertion same() uses the same parameters as equals(), but it works not only with primitive types, but also with arrays and objects. The statements from the previous example will pass the test if changed from to identity statements:

    Test("test", function() ( same((), (), "passes, objects have the same content"); same((a: 1), (a: 1) , "passes"); same(, , "passes, the arrays have the same content"); same(, , "passes");

    Please note that same() uses the '===' operator for comparison, so it is convenient to use for comparing special values:

    Test("test", function() ( equals(0, false, "true"); same(0, false, "false"); equals(null, undefined, "true"); same(null, undefined, " false"); ))

    Statement Structure

    Placing all assertions in one test is a very bad idea. Such a test will be difficult to maintain and you can get confused in evaluating the results of its execution. Therefore, you need to structure the test by placing statements in separate blocks, each of which will be aimed at a specific group of functions.

    You can organize individual modules using a function call module:

    Module("Module A"); test("Test", function() ()); test("Another test", function() ()); module("Module B"); test("Test", function() ()); test("Another test", function() ());


    In the previous example, all statements were called synchronously, that is, they were executed one after another. There are many asynchronous functions in the real world, such as AJAX requests or functions setTimeout() And setInterval(). How do we test this type of functionality? QUnit has a special test type called "async test" which is designed for asynchronous testing:

    First, let's try to write a test in the usual way:

    Test("Asynchronous test", function() ( setTimeout(function() ( ok(true); ), 100) ))


    It looks like there are no assertions in the test. Because the statement was executed synchronously, but by the time the function was called, the test had already been completed.

    The correct way to test our example is:

    Test("Asynchronous test", function() ( // Put the test into pause mode stop(); setTimeout(function() ( ok(true); // After calling the assertion // continue the test start(); ), 100) ))


    We used the function stop() to stop the test, and after executing the assertion, run the test again using the function start().

    Calling a function stop() immediately after calling the function test() is a very common practice. That's why QUnit has a special abbreviation: asyncTest(). The previous example can be rewritten as:

    AsyncTest("Asynchronous test", function() ( // The test is automatically switched to "pause" mode setTimeout(function() ( ok(true); // After calling the assertion // continue the test start(); ), 100) ) )

    There is one point worth thinking about: the function setTimeout() always calls its callback function, and if testing another function (for example, an AJAX call). How can you be sure that the callback function will be called? If the return function is not called, the function start() will also remain uncalled and the entire test will freeze:


    You can organize the test as follows:

    // Custom function function ajax(successCallback) ( $.ajax(( url: "server.php", success: successCallback )); ) test("Asynchronous test", function() ( // Stop the test and // report an error if the start() function is not called after 1 second stop(1000); ajax(function() ( // ...asynchronous statement start(); )) ))

    To function stop() the timeout value is transmitted. Now QUnit is told: “if function start() will not be called after the timeout expires, this test should be considered failed.” Now the entire test will not freeze and a warning will be issued if something goes wrong.

    Now consider the case of multiple asynchronous functions. Where to place the function start()? You need to place it in a function setTimeout():

    // Custom function function ajax(successCallback) ( $.ajax(( url: "server.php", success: successCallback )); ) test("Async test", function() ( // Stop the test stop(); ajax (function() ( // ...asynchronous statement )) ajax(function() ( // ...asynchronous statement )) setTimeout(function() ( start(); ), 2000 ));

    The timeout value must be sufficient to allow both callbacks to complete before the test continues. If one of the functions is not called, how can we determine which one? There is a function for this expect():

    // Custom function function ajax(successCallback) ( $.ajax(( url: "server.php", success: successCallback )); ) test("Asynchronous test", function() ( // Stop the test stop(); / / Tell QUnit that we expect three statements to be executed expect(3); ajax(function() ( ok(true); )) ajax(function() ( ok(true); ok(true); )) setTimeout(function( ) ( start(); ), 2000 ))

    We pass to the function expect() the number of statements that are planned to be executed. If one of the statements fails, you will receive a message indicating that something is not going as planned.

    There is a short recording for you to use expect(): you need to pass the number of scheduled statements as the second parameter test() or asyncTest():

    // Custom function function ajax(successCallback) ( $.ajax(( url: "server.php", success: successCallback )); ) // Tell QUnit that we expect 3 statements to be executed test("asynchronous test", 3, function() ( // Stop the test stop(); ajax(function() ( ok(true); )) ajax(function() ( ok(true); ok(true); )) setTimeout(function() ( start (); 2000);

    Conclusion

    In this tutorial we have provided everything you need to get started with QUnit. Unit testing is a great method for testing code before using it. If you've never used any tests before, now is the time to start.

    Testing for knowledge of the following topics is now available on the site: HTML, CSS, JavaScript, PHP, SQL.

    Each test consists of 10 questions on a specific topic. In each question, I tried to cover the most diverse areas of application of a particular language in order to test your level of knowledge as thoroughly as possible.

    Of course, all tests are free and anyone can take them.

    Test procedure:

  • Follow the "Start testing" link for the corresponding test.
  • Answer the questions posed by choosing the only correct option.
  • Upon completion of the test, you will see your score, the number of errors, as well as an analysis of each question from the test.
  • Attention! You won't be able to go back to the previous question, so think before answering.

    Currently available tests
  • HTML
    • Total test taken: 75,424 people
    • Average score: 2.83 out of 5 points.

    HTML Basics Test. You will need knowledge of basic HTML tags, as well as their competent use. It is also necessary to understand the features of the XHTML 1.1 standard.

  • CSS
    • Total test taken: 32828 people
    • Average score: 3.37 out of 5 points.

    The test tests knowledge of CSS basics. To successfully pass the test, you must know the main types of selectors (their syntax), know the basic properties and their possible values, and also know the purpose of the most popular pseudo-elements.

  • JavaScript
    • Total test taken: 24845 people
    • Average score: 3.31 out of 5 points.

    This test tests your knowledge of the JavaScript language. The test questions cover different areas of application of this language. There are a lot of questions about understanding “small” nuances. Otherwise, you are required to know basic things: working with variables, basic JavaScript functions, operation priorities, etc.

  • PHP
    • Total test taken: 33,239 people
    • Average score: 3.03 out of 5 points.

    This test tests your knowledge of the PHP language. You are required to know basic PHP constructs, working with variables, sessions, implementing redirects and other standard things.
    We kindly request: The test contains many questions like: “What will the script output?” Please don't copy it or check it. Be honest with yourself.

  • SQL
    • Total test taken: 18,014 people
    • Average score: 3.28 out of 5 points.

    This test tests your knowledge of the SQL query language. The questions cover only the most basic knowledge of this language, without any depth. You will need knowledge of the most basic SQL queries, as well as their competent use.