The main thing you need for testing is an assert function. This is one thing that EcmaScript lacks (for some strange reason). A simple assert function could look like this:

function assert(condition, message) {
    if (!condition) {
        message = message || "Assertion failed";
        if (typeof Error !== "undefined") {
            throw new Error(message);
        throw message; // Fallback

Some browsers support console.assert though.

You often need to check more than just a simple boolean expression. Asserting that two objects are equal (by comparing their properties) is one example. A assertion library that I often use is chai.

The next thing to consider is test automation. I've done some research with CasperJS, PhantomJS and Selenium webdriver. CasperJS, which is based on PhantomJS, and PhantomJS support headless testing and are newer than Selenium which been around for some time. Headless testing measns that you run the tests without a traditional browser which is handy when automating tests. My choice ended up on Selenium, CapserJS and PhantomJS did not have all the features that I needed when the scenarios become a bit more complex (using iframes etc). These tools provide support for end-to-end testing.

Unit testing across many browsers is best done with Karma. Karma runs the tests in all major browsers. There is also support for services that runs the tests in many browsers for you, like SauceLabs (free for open source projects). There is also testing frameworks that helps you structure the tests. The two main competitors are Jasmine and Mocha. I've ended up using Mocha, but the choice is a matter of taste. Jasmine and Mocha are both supported by Karma.