Tuesday, July 30, 2013

Running Browser and Server Test Together


I think my fake test server for functional testing Dart browser code is in pretty good shape. I also think I have a pretty good handle on the scheduled_test package that I have been exploring for the past few nights. But if I have learned anything over the past few years, it is that even when I think I know something, I don't. So tonight, I am going to write a few new tests for my fake test server.

I am extracting this out from Hipster MVC, so I already have a REST-like feature built into the server that allows tests to GET and POST to a /widgets resource, as well as PUT, DELETE, and GET to /widgets/:id resources. I hope to use Schedule Test to verify that it works.

To add to the degree of difficulty, I am going to test this with HttpRequest from the browser side of things. In Dart, there are two different HttpRequest classes: one for the server side and one for the browser. I have been testing from the server side, which means that I have been using the dart:io library. If there is a Node.js equivalent in Dart, then it is in the dart:io library.

In addition to making servers easy to write, it also makes testing servers nice as well. But in my case, most of the uses of this fake test server will come from browser code. Instead of dart:io, I will be using the HttpRequest from dart:html. This HttpRequest is a Dart version of the venerable XMLHttpRequest object from JavaScript.

Unfortunately, the two libraries cannot co-exist. It makes no sense to allow browser code to execute dart:io code like writing to the file system. Actually that would be a pretty horrendous security violation which is why dart:io classes are not in core Dart and not available in the browser. So the only way to have both dart:io and dart:html tests in the same test suite is to run two separate processes. Which is where Bash comes in...

My test/run.sh script will start by running the server code that I have been building over the past few days:
#!/bin/bash

###
# Test the server with server tools
echo "Running dart:io tests"
dart test/server_test.dart
That all works with no changes.

Next, I need to execute my client tests. This is slightly more involved in that I need to start a server, run content_shell against my browser test page (browser tests need a web page context), parse the output, and stop the server. Fortunately, I have gotten good at this:
#!/bin/bash

###
# Test the server with server tools
echo "Running dart:io tests"
dart test/server_test.dart

###
# Test the server from the browser
echo
echo "Running dart:html tests"

# Start the test server
dart test/dummy_server.dart &
server_pid=$!

# Run the actual tests
results=`content_shell --dump-render-tree test/index.html 2>&1`
echo $results
echo "$results" | grep CONSOLE

echo "$results" | grep 'unittest-suite-success' >/dev/null

echo "$results" | grep -v 'Exception: Some tests failed.' >/dev/null

# Stop the server
kill $server_pid
rm -f test.db test/test.db
I think that works. To be sure, I need to write some Scheduled Test tests. But I have a #pairwithme session tonight, so I think it makes sense to call it a night there. I will pick back up with the new Scheduled Tests tomorrow.

Day #828

No comments:

Post a Comment