Node.js and coffeescript -- testing app with Mocha and Zombie - node.js

I am trying to test a node.js webapp I have started working on with
Mocha and Zombie. But there are a few things I still don't understand
and would like some help. Please note that I am using express
Suppose I am testing the user authentication. Obviously there are two
parts:
1 - the user interface
2 - the behavior, involving the controllers and the models
So, I've decided to separate both parts. For the UI, I have decided to
use zombie. The following link contains the UI tests I've written for
the user authentication: https://gist.github.com/7e45d6884ce2d32e933d
Basically, my user authentication form contains a username and
password input fields and a Sign In button. I am interested in four
scenarios: when at least one of the input field is empty and when both
have been provided by the user.
Although the four tests pass right now, I am still not convinced they
are the right tests, or whether it's enough or does the right thing.
What do you guys (BDD experts) think?
thanks
José

Since your tests seem to be asynchronous, you should be calling the done function given to the callback of the it function
it 'should do something', (done) ->
browser.visit 'somepage', {debug: true}, ->
done()
You might also want to check for the error message your app prints when there is an error authenticating.
Besides checking all the fields are given, you should also test a valid authentication, a wrong password, and existing username if your app provides that error message. And if you went as far as only allowing a number of attempted logins every few minutes, test for that too.

Related

Test environment beside practical environment for nodejs applications

Before I asked, I`ve searched a lot and there are many articles about it. But my question is a little deeper.
I have an application using Nodejs Expressjs + MongoDB + Reddit + PM2 clustering mode + Bitcoin and card getaway + API system.
My problem is when I'm developing this application in real mode and it`s really awful. sometimes I release little updates in codes, and I press "pm2 log" it shows me some error in syntax or something else and I try to fix that and release again. During this time, the application with many users is down.
Also, I have to say something such as Bitcoin payment, needs real tests. Needs request and response from Blockchain. How can I have a test environment that I can test everything exactly same as real mode and then if everything was fine, then deploy that to real mode?
An environment that easy to code and test then easy to deploy? Can Mocha help me exactly what I need? I`m using PM2 clustering mode.
Your question is not a proper question, but rather a layer of questions, some opinion-based, some too broad to answer. But let's try breaking it down.
The stated problem is when I'm developing this application in real mode.... I release updates ... it shows me syntax error... application is down. I will read it as the main problem is that you're developing on a production environment. Let's forget for a while how lousy a practice that is, and let's focus on something constructive.
Let's define rough steps to take.
Live environment
The most pressing problem seems to be that you work on live app, where crashing it during dev means crashing it for your users as well. Let's deal with that.
Immediatelly change all your access codes, keys, usernames and passwords so that you store them in an environment file (which is safe to encrypt and backup, but not commited in source code), say, environment-prod.env.
Then create a second set of credentials for all the services that you use. For MongoDB, e.g. it's easy, just create a local database instance, called, say, test_database. For Reddit, create a second app, cal it my-app-test, for example. Some services might have an option to create a set of test credentials right there in the app, with others you'll simply have one app for test, one for production.
Create a new environment file, e.g. test-environment.env, with all the same keys (e.g. REDDIT_APPID, REDDIT_SECRET, MONGODB_URL, BLOCKCHAIN_GATEWAY_KEY etc), but new values.
Now, for one, you have a test environment. Make an alias, e.g. alias dev="cd $HOME/projects/my-reddit-bitcoin-app && source test-environment.env". Every day you come to work on the app, type dev, then you can start pm2 etc and work safely in dev environment. Your users will never see your crashes.
Only when you're sure you have a new feature or bugfix completed, switch environment (source environment-production.env) and then deploy the new app to the server where it runs, and pm2 restart or whatever you use for these deployments. Switch back to test env immediately before working on the code anew.
Read up more on how to separate test/prod environments. Read a bit on git workflows (e.g. branch off of latest master to a feature-branch or bugfix branch, when tested, merge it back in. Then tag it "release-" and deploy to production. Then go automate all that if possible.)
Testing
Mocha is perfectly suitable for running tests for a Node/Express app. It's the tests that matter.
You say bitcoin payment....Needs request and response. Let's see how to do that.
Add [nock])(https://www.npmjs.com/package/nock) to your app (npm i -D nock).
import it and put it on top of your test file. E.g. at the top of the some-test.spec.js file:
const nock = require('nock')
start recording requests e.g. add this in your before() block in the app:
describe('My tests', function () {
before(function () {
nock.recorder.rec();
});
// ... tests
Now, run one test at a time (e.g. write one test that does one specific task from your app) and check what's in the console. E.g. if you make a request (request.post('http://reddit.com/api/submit', jsonData)), you'll see nock printing the exact response (in JSON format) in console, as the test runs. Copy that in the test file, e.g. put it at the bottom as:
var testResponse = <whatever was in the console in json format. Or string, whatever>. // homework is to find out why var and not const, if this is at the end of the file.
Now stop the recorder (comment it out), and in your actual test, run this instead:
const pipe = nock('http://www.example.com')
.get('/resource')
.reply(200, testResponse);
do that for all your requests.
Now what you have is a test setup so that when you change the code, it should not run against the real Reddit api, or real payment gateway api, but get your mocked responses instead. Pair it up with some good assertions and you should be fine. Make sure you mock everything. If you add new types of requests, make sure to record them, and add them to your procedure.
Now, all this is very vague. Broad. Just one way to do it. Lengthy process. Probably not the best one. Not tailored to your specific conditions. But it should get you started. Take those things, step by step, and if you get stuck, come back to Stackoverflow. But do start working on it, because your current method seems to be unsustainable in the long run.

Sails authentication is allowing me to hit endpoints without any tokens...

I followed this tutorial :
http://blog.cendekiapp.com/2015/04/02/add-authentication-in-sailsjs-api/
and when I want to run the app, it works fine when I run :
sails lift
But, if I try and hit endpoints via a rest client... it will return me data, without any kind of login being necessary...
I notice the comments, and people are having the same issue - my code is IDENTICAL to the one in the example, and is even built on top of the tutorial from part one (before the auth tutorial)
if I hit http://localhost:1337/user - it will return me all users, I am sure it needs to be checking for a token, which I would get via checking if I have one to submit, or go get one from the login controller, but I am not sure what I need to do. Anyone have any ideas? Or know straight up what is missing?

Unable to log in to Azure web app via VS2015 web performance test

How do I correctly handle the login/authentication scenario for an Azure web app in my VS2015 web performance test?
I created an XML file as a data source for the WAAD username and password. I bind the username and password to the Form Post Parameters: login and passwd respectively at request: https://login.microsoftonline.com/xxxx/login
But when I run the test, the Web Browser tab shows this error:
We can't sign you in
Your browser is currently set to block JavaScript. You need to allow
JavaScript to use this service.
To learn how to allow JavaScript or to find out whether your browser
supports JavaScript, check the online help in your web browser.
I also get a number of errors like this:
The value of the ExpectedResponseUrl property
Validation xxxx.azurewebsites.net/xxxx/docs/xxxx.aspx does
not equal the actual response URL
login.microsoftonline.com/xxxx/wsfed. QueryString
parameters were ignored.
Any idea how I can successfully log in to the Azure web app via the web performance test?
There are several methods of login and authentication that can be used. Just binding values to form post parameters may not be sufficient or correct. You will find the login form has hidden session identities that must be passed as well as the login data. I find that recording a test two times using as nearly as possible the same inputs and doing the same activities helps. These two tests can then be compared to find the dynamic data that needs to be handled.
In a comment the questioner added "I noticed these parameters, n1-43 are different but I have no idea what they represent. How do I handle them?". I can have no idea what they represent as I do not know the website you are testing. You could ask the website developers. Or, better, treat them as dynamic data. Find where the values come from, save them into context variables and use them as needed. This is basic web test development. Here and here are two good articles on what to do.
The message about JavaScript not being supported can be ignored. Visual Studio web tests do not support JavaScript or any other "active" parts of a web page, they only support the html part. Your job as a tester is to simulate what the JavaScript does for the specific user journeys you are testing. That simulation is generally just filling in the correct values (via context parameters) in the recorded requests.
Unexpected response urls can be due to earlier failures, such as teh login not working. I suggest not worrying about them until all of the other test problems are solved. Then, if you need help ask another new question.

node.js: writing test cases for social networking like APIs

I'm developing APIs for social networking web application for learning perspective. When I started to write test cases I stuck around how to organize/write test cases.I'm initially proceeding like this:
First setup global data base initialization:
I need some users' auth tokens to test my routes so I decide to set up these information at global context. Also there are other information that also need to setup at global context so I'm setting that too.
Then for each route:
I start to write test cases and thought that I would write test cases in
such a way that each route test cases would be independent to each other.
and after completing all test suites:
I thought that I would clean up my data base.
The problems with this approach I'm facing are:
Say I want to test four routes named /users , /users/:id/my_invites , /send_invites, /response_invites. And further suppose I'm only interested in writing test cases for GET request and response for /users , /users/:id/invites and POSTing data in the case of others.
/send_invites, /response_invites definitely trigger some actions on the server side that modifies the data base state.
As we see that these routes effect the state of other routes' data say one user sends invites to another user and gets response true/false, so for that user his request was successful but how to ensure that another user actually received the invitation if we don't checking his received invitation documents(i.e through another route) in the first route test cases. Means /send_invites effects the /users/:id/my_invites .
because these routes are dependent on each others
So The questions I want to ask are:
how to write test cases for these routes so that each route would be independent ?
I tried with three dummy testing users in the global context and trying all sort of combinations for them in all test suites.My test suit presently deals with more than one routes to check 1 route true functionality.
Can anyone suggest me better solution for writing test cases for the above mentioned scenarios?
May be my question is too long or not clear. Please let me know and help me if you can.
My opinion:
First the bases EACH test case should have a fresh new state. That means that before you check one scenario, you want to flush your database and insert your new data prepared to test that case scenario. You can use a real database o mock one with data in-memory or however you prefer.
Second, each endpoint potentially affects a lot of tables in your database. So it's perfectly normal to check the state of your data, independently of the tables to check that the information is correct.
And well mocha and other test frameworks have functions that help you to do that. Like beforeEach and afterEach to set up and tear down your data before each test case.

Two concurrent requests getting mixed up in Node.js app

I am completely stumped by what I noticed today in my app.
I have an app written in Node.js running on nginx with MongoDB in the backend. I have an 'authenticateUser' cal which takes in a username and password. It then queries MongoDB to retrieve the users document and checks if the password matches up.
We wrote a script which basically calls 'authenticateUser' in a loop 100 times. It worked fine. No errors. Now we ran the same script from 2 terminals, one for user bill and the other for user sam. We started seeing failures on both the terminals. I would say about 10% of the requests failed with invalid password errors.
When we inspected the log files, we were completely surprised to see bill's username getting mixed up with sam's password. We have no idea what's going on. We must be doing something obviously wrong. What is it? Aren't the two requests completely isolated from each other?
Do you use global variables often? Missing var is a common cause of such errors.
And yeah, i'd like to see a source code...

Resources