baseapp provides all the boilerplate to get your JavaScript web application started off right, this Part 3.
- Intro to baseapp
- Client-Side Unit Tests
- Server-Side Unit Tests
- WebDriver Integration Tests
- Other Grunt Goodies
- Authentication
- Continuous Integration
- Administration
baseapp handles server-side unit tests using jasmine-node and istanbul for code coverage. The grunt task to run the tests is 'grunt jasmine_node_coverage'. The tests always run with code coverage enabled.
Unlike the client-side unit tests I do not use any third party grunt plugin to execute this grunt task. Let's go to the configuration!
jasmine_node_coverage: {
options: {
coverDir: 'public/coverage/server'
, specDir: 'spec/server'
, junitDir: './build/reports/jasmine_node/'
}
}
Not a lot here - 'options.coverDir' is the directory where coverage information will be dropped, 'options.specDir' is where all of the server-side unit tests live, and finally 'options.junitDir' is where the JUnit XML test output (one file per suite) is placed.
Jasmine-node works almost identically to client-side jasmine. The biggest (only?) difference is how asynchronous tests are handled. While both jasmines match 'runs()' and 'waitsFor()' functions to handle asynchronous tests, jasmine-node also provides 'jasmine.asyncSpecDone();' matched with 'jasmine.asyncSpecWait();' to handle async tests easier.
Let's take a look at the userSpec.js suite. This file unit tests the authentication code in routes/user.js. Unlike the client-side tests these tests are not run in a browser and objects under test are pulled in via the normal 'require' method.
In this case I expect the redis database to be up, you can use jasmine spies to mock it all out, but instead I select redis database '15' to not interfere with production data (redis has 16 databases named 0-15, by default you get database 0 unless you change it as I do in the 'select' call).
Also I have an 'afterEach' method that completely blows out the contents of the redis database after each test so I'm guaranteed each test gets a fresh database (redis.flushdb()).
The async tests themsevles are very straightforward, just call methods and verify resopnses, easy peasy.
Application Architecture
A quick note about ease of testing, you will note in user.js, I was clear about separating HTTP from the functionality of the module to make testing easier. I was very careful to not mix dealing with HTTP-protocol based values with authentication routines. I specifically did not want to mix up HTTP with authentication to make testing easier. This way I do not have to mock/deal with HTTP when testing the authentication routines. Be sure to keep separation of concerns in mind while writing your code. Writing tests first will help keep your code clean.
Code Coverage
Istanbul has great integration with jasmine-node, looking further down in the Gruntfile you can see the implementation of the jasmine_node_coverage task. Simply running istanbul with jasmine-node will automatically generate code coverage and the coverage output is written to 'public/coverage/server/lcov-report/index.html' in fancy HTML.
This is the first time I've seen this post, and as a newcomer, I find it incredibly intriguing. Your Glee essay about Server-Side Unit Tests taught me a lot. Thank you for sharing this. You may always receive support from your list of dissertation topics in higher education service, which is a useful tool for students. I always come here for assignment assistance.
ReplyDeleteThis is the first time I've seen this post, and as a newcomer, I find it incredibly intriguing. Your Glee essay about Server-Side Unit Tests taught me a lot. Thank you for sharing this. You may always receive support from your list of dissertation topics in online essay writing service service, which is a useful tool for students. I always come here for assignment assistance.
ReplyDeleteIn fact, adult males have a strong need for this custom sexdolls.
ReplyDeleteI liked the part where you described spinning up a real server connection and assigning a user ID instead of mocking everything out—it feels a bit unconventional, but also more grounded in how the app actually behaves. That detail about testing internal APIs directly rather than isolating every component really stood out, especially since a lot of discussions around unit testing lean heavily toward mocks and strict isolation. It makes me wonder if this approach ends up catching issues that more “pure” unit tests might miss, or if it ever slows things down as the codebase grows.
ReplyDeleteIt also got me thinking about how people approach clarity in different domains—like when someone uses an English Assignment helper Online, they’re not always trying to isolate every detail, but rather see how things work together in a more complete flow. Do you still find this method scales well as projects become more complex, or does it start to blur into integration testing territory?