Take adding two integers, you can test 3+18= 21 or you can assert that, when both arguments are positive, the result is greater than each argument.
Take adding two integers, you can test 3+18= 21 or you can assert that, when both arguments are positive, the result is greater than each argument.
expect(add(A, B).toBeGreaterThan(A);
expect(add(A, B).toBeGreaterThan(B);Say you have a CRUD api (TheTrackerOfWidgets), and you want to test a create Widget call. Widgets can have a name, size, and each is associated with a unique id.
Your property test might look like (in pseudo-rust):
#[quickcheck]
fn created_widgets_exist(name: String, size: u32) -> bool {
let resp = create_widget(&name, size);
if !resp.is_valid_json_or_whatever() {
return false;
}
let id = resp.get_id();
let resp = retrieve_widget(id);
if !resp.is_valid_json_or_whatever() {
return false;
}
resp.get_name() == name && resp.get_size() == size
}
You would probably go further and not use default types but instead use bounded types based on any domain specific verification logic you have. Note that nowhere does it actually assert that a response looks exactly like what you expect, you assert that it is valid and/or satisfies some property (that created widgets exist and are accessible by further api calls).Exact results still have to be created manually or automatically (randomly) created and the result manually checked once.
For a CRUD app, I've also created random account generators that can randomly create all different sorts of accounts, based on the database layout. You can then even do things as simple as "render the view screen on this user account", and, again, you might be surprised what pops out. Plus, as you continue building the system, you can both extend your "random account generator" to generate more and more random things, and use it on more and more of your code. This is when you can discover that your page crashes if they don't have exactly the same number of shipping addresses and phone numbers, or your forum crashes on users who didn't enter the optional email contact address, or whatever. Also, as you have the ability to easily generate "100 fairly random accounts", you'll find other interesting tests that you can write.
Simple number comparisons are just an easy example.
If your CRUD app happens to extend just a wee bit beyond the boringest possible CRUD and you also have any sort of structured test you need to accept, you can also use a fuzz tool like http://lcamtuf.coredump.cx/afl/ You can find all sorts of interesting things in any sort of structured text input that way quite easily. (Theoretically, if you're motivated, you can even hook up a fuzzer to the random account creator idea above, but that does take a bit of work, but that would do interesting things if you could get it going. I've only used something like afl a few times, but it's kinda fun, and amazing.)