I am brand new to creating unit tests, and attempting to create tests for a project I did not create. The app I'm working with uses python/flask as a web container and loads various data stored from js files into the UI. I'm using pytest to run my tests, and I've created a few very simple tests so far, but I'm not sure if what I'm doing is even relevant.
Basically I've created something extremely simple to check if the needed files are available for the app to run properly. I have some functions put together that look for critical files, below are 2 examples:
import pytest
import requests as req
def test_check_jsitems
url = 'https://private_app_url/DB-exports_check_file.js'
r = req.get(url)
print(r.status_code)
assert r.status_code == req.codes.ok
def test_analysis_html
url = 'https://private_app_url/example_page.html'
r = req.get(url)
print(r.status_code)
assert r.status_code == req.codes.ok
My tests do work - if I remove one of the files and the page doesn't load properly - my basic tests will show what file is missing. Does it matter that the app must be running for the tests to execute properly? This is my first attempt at unit testing, so kindly cut me some slack
While testing is such a big topic, and does not fit in a single answer here, a couple of thoughts.
It's great that you started testing! These tests at least show that some part of your application is working.
While it is ok, that your tests require a running server, getting rid of that requirement, would have some advantages.
you don't need to start the server :-)
you know how to run your tests, even in a year from now (it's just pytest)
your colleagues can run the tests more easily
you could run your test in CI (continuous integration)
they are probably faster
You could check out the official Flask documentation on how to run tests without a running server.
Currently, you only test whether your files are available - that is a good start.
What about testing, whether the files (e.g the html file) have the correct content?
If it is a form, whether you can submit it?
Think about how the app is used - which problems does it solve?
And then try to test these requirements.
If you are into learning more about testing, I'd recommend the testandcode.com podcast by Brian Okken - especially the first episodes teach a lot about testing.
Related
When I used to program with python I could run a python app and then execute methods and access variables of the app from within terminal. This was a great way to test things around.
Working on my JS app I often use console.log to try things out but I am looking for a way to try things without having to rerun the app each time. I want to be able to call any method / variable of my React app (including imported classes etc) from within console "at run-time".
Is this possible? If yes, how?
If not, what is the best alternative to switching between code and browser back-and-force to see the effect of certain changes console.log ?
So, I'm trying to use a web worker in my project to run a long-running process that is currently tying up the UI. I've been to I don't know how many sites trying to get a worker to work, but to no avail.
All of my javascript is kept in separate files and referenced in the HTML file. As a test to get my feet wet, I created a test.js file and put the following code in it:
self.addEventListener('message', function(e) {
self.postMessage('return');},false);
Then, in the UI page's javascript file I placed this code in a function triggered by a button click event:
var w = new Worker('test.js');
w.addEventListener('message',function(e){
alert(e.data);},false);
w.postMessage('hi');
The code is derived from:
html5rocks.com/en/tutorials/workers/basics
Other websites I visited provided similar instructions on how to set up a worker.
For the life of me, I cannot get this to work. When I execute it does absolutely nothing and I seemingly get no errors. Stepping through the code, it appears to create the worker, but I don't see any evidence of the event listener being created and the 'postMessage' event doesn't do anything. I've tried IE11 and Chrome with the same results.
In my research, I came across a part of Chrome's developer tools that revealed the test.js file couldn't be found. Yet, the file is in the same folder as the page's js file. So, I tried adding in the relative directory information as I do in the page's HTML section. That didn't work either.
I then found claims that for security reasons you couldn't have one js file reference another js in the code. It's unclear whether this is a Chrome-only feature or part of some spec.
So, now I'm in a quandary. The worker requires a reference to a separate js file for the code to be executed, yet, the browser isn't allowed to reference another file? How is the worker supposed to work if you aren't allowed to do what it requires to work?
To now, I've successfully pissed away two days trying to get this one seemingly simple function to work. To say I'm mildly frustrated would be an understatement. Being a fairly novice programmer and not understanding every last little nuance about web programming I'm clearly missing a key part of this whole thing.
How the heck is one supposed to make web workers work?
Turns out browsers won't allow local files to be fetched via javascript. Because that means a website can read your personal files! So you need to develop and test your project using a web server. The easiest way to do this for me was to install:
docker-compose
and make sure it works. Then create a file named:
docker-compose.yml
inside root folder of my project with index.html file. Then put this inside the docker-compose.yml file:
version: '3'
services:
nginx:
image: nginx:alpine
volumes:
- .:/usr/share/nginx/html
ports:
- "80:80"
Then inside the root folder of my project run:
docker-compose up
And then in the browser go to:
http://localhost/
And it worked!
I appear to have found a solution, though it escapes me why.
If I use:
var w = new Worker('js\test.js');
the worker doesn't work.
But, if I use:
var w = new Worker('js/test.js');
the worker does work.
I characteristically use the back slash throughout the project to delineate paths without issue. Why the forward slash must be used to set the worker's file location is a mystery. I have seen nothing in any documentation that even remotely addresses that tiny, yet seemingly critical detail.
Thank you, Mr. Starke, for your help!
In Python there is a neat thing like this:
if __name__ == "__main__":
runTests()
So this runs runTests() only if the file was run separately and not imported. When the file will be imported it will not run the tests.
So I want to create some kind of modules for my tests in Instruments UI Automation - but I also want to test the module itself.
Is there any global variable that I can check to see if the current file is being run as a main file or as an imported one?
Good question, unfortunately the answer is no. If you are looking for something like the __name__ variable in python it does not exist. A hacky workaround that isn't really a solution to your problem (as it would require you to edit your test script before running), you could set a global variable prior to your inputs
var BEING_RUN = false;
#import "path/to/jsFile.js"
with an if statement in each file
//BEING_RUN = true;
if (BEING_RUN) {
doStuff();
}
and you could uncomment BEING_RUN = true; only on the file(s) being run. Again, this is not really a solution but it may suit your needs.
My recommendation would be to structure your test library in such a way that you don't import things from files that also contain UI tests. So you should put functions and other things that are used by your tests in files that get imported, and only have the actual simulation of user interaction in your test files. I'd also suggest checking out tuneup.js (http://www.tuneupjs.org/) it makes iOS UI Automation much more pleasant.
I wrote some UIAutomation test cases to test my app, but I didn't find anyway to run each case from beginning. When a test case failed would cause other cases failed as well. Is there any way let UIAutomation run each script from app beginning. I means when a test failed app can quit test and continue run second test from beginning.
I also used tunneup.js to write my scripts. In a test.js file the structure of scripts are:
test("test1", function () {
some code.
});
test("test2", function () {
some code.
});
Currently when test1 failed, would let test2 failed as well, I want when test1 failed app can quit and start again to run test2 case.
One thing I'd suggest is to keep your test cases independent from one another so you don't get cascading failures. Nonetheless, you can setup a base state so your automation can "recover" and continue with the remaining test cases. For example, if you have a main view, start your test cases by making sure you're at the main view before continuing.
I would like to quote few points, that will help you in building good test scripts.
1.Try to maintain a different scripts for different test cases that will help you in solving the problem of not reaching the next test case.
2.Try to maintain some reusable scripts, like going to home from any point or moving to a particular screen when needed and import them in the scripts, which will help you in reaching to test case easily in each of the different script.
I am answering this question knowing that you have knowledge of writing and importing scripts. If no , please do comment with you query.
I'm looking for framework which provides unit tests for JS. Later, I'll have to integrate it with CruiseControl.NET. I have a lot of asp websites using JS and I need to automate testing for them. For example I used local JSUnit (may be other framework), which was quite easy for me, but I have no idea how to integrate it with CC.NET. Maybe you can show me how to start with ?
NOTE: it must be CC.NET, framework for unit test not specified
I realize this is a rather old question, but I have had similar interests so I figure I would post an answer regardless. I am assuming you are writting OO style JavaScript and wanting to test those objects.
A common solution recommended by people is to run JsTestDriver and this is definitely a great tool; that being said, it requires the JVM to be installed on your machine as well as the build server. In addition to requiring the JVM, JsTestDriver is still dependant on running one or more 'Slave' browsers. Personally, I believe that should not be a concern when unit testing JavaScript objects. If the focus is UI testing, then using a tool such as WatiN and is a different type of test in my opinion. The browser should be mock out like you would mock out any other view using JSMock or JsMockito (which I like best).
To that end, I have used Windows Script Host to run my JavaScript unit tests for years. This has several advantages:
No Browser Required (to me that is a good thing).
CScript is already on every Windows machine since XP; so nothing to install.
Runs in background process and does not require an interactive UI when running tests.
Since running inside MSTest, NUnit or xUnit etc, integrating with CC.NET, Hudson, or TeamCity is as easy as running your unit tests as a part of the build.
Full debug support simply by running your unit test inside the debugger.
There are a couple of disadvantages of course:
The machine running the unit tests has to have the ability to spawn off new processes (CSCript) to actually run the tests (has yet to be an issue).
Slower that running regular unit tests (A little over 1,000/minute on an older dual core if run individually - i.e., not bundled together in a single CSCript process).
Using JSTest.NET (approach I have used for years but just posted online), you end up with a test fixture that may look similar to the following:
using JSTest;
using JSTest.ScriptLibraries;
using Xunit;
namespace JSTest.Sample
{
public class EventDispatcherTests
{
private readonly TestScript _testScript = new TestScript();
public EventDispatcherTests()
{
//Append File(s) Under Test.
_testScript.AppendFile(#"..\..\..\Web\Scripts\eventDispatcher.js");
//Append Mock/Assertion libraries.
_testScript.AppendBlock(new JsHamcrestLibrary());
_testScript.AppendBlock(new JsMockitoLibrary());
//Append Common "Setup" Scripts.
_testScript.AppendBlock(#"var dispatcher = new EventDispatcher();
var mockHandler = JsMockito.mockFunction();
var mockPredicate = JsMockito.mockFunction();
var fakeEvent = { eventType: 'CommentAdded', data: 'Sample Comment' };
");
}
[Fact]
public void ProcessEventInvokesAttachedHandler()
{
...
}
[Fact]
public void ProcessEventGracefullyHandlesPredicateException()
{
_testScript.RunTest(#"var mockPredicateAlternate = JsMockito.mockFunction();
JsMockito.when(mockPredicateAlternate)(fakeEvent).thenThrow('MyException');
dispatcher.attachListener(mockHandler, mockPredicateAlternate);
dispatcher.processEvent(fakeEvent);
JsMockito.verify(mockPredicateAlternate)(fakeEvent);
JsMockito.verifyZeroInteractions(mockHandler);
");
}
}
}
This approach works well for me, and is very simple to setup. Basically, it is like writing regular unit tests, but with JavaScript.