That's an interesting thought! My first gut reaction is just that the packages were designed with different goals and so are better optimized for their strengths. testthat was designed for unit tests and so has a bunch of wrappers that do a handy job of monitoring which unit tests pass / fail, etc. (You should check out the new testthat - it produces really pretty output! Not sure if the new version has hit CRAN yet).
assertthat has the same creator/maintainer and is explicitly created with run-time assertions in mind (as a replacement for stopifnot).
On the practical front, though, I think the focus may be on the types of error messages issued. assertthat advertises that it:
makes it easy to declare the pre and post conditions that your code should satisfy, while also producing friendly error messages so that your users know what they've done wrong.
Usually, expect_equal (in testthat) expects to have the parent test_that script pick up any errors and relay the message that a unit test failed, so I think the quality of the error message may be lower when using testthat at runtime.
Additionally, there are probably some edge cases or internals that have a different thought process. The help page seems pretty adamant on assertthat:
Assertion functions should return a single TRUE or FALSE: any other result is an error, and assert_that will complain about it.
I expect that there is a reason for that specificity. I just don't know it. I'm sure @hadley would have some more thoughts on the differences between assertthat and testthat.