In search of JavaScript code quality: unit testing


Published on

  • hi
    we looking for developers
    Skype: michael.grossman
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

In search of JavaScript code quality: unit testing

  1. 1. AGENDA Unit Testing Concept Why Unit Testing? Test Driven Development (a.k.a. TDD) Basic Terms & Structure Tools & Libraries Unit Testing Specifics in JavaScript Best Practices
  2. 2. UNIT TESTING CONCEPT Unit testing is a method by which individual units of source code are tested to determine if they are fit for use. Unit is the smallest testable piece of code. Unit tests are created by programmers.
  3. 3. COMMON SENSE OR WHY UNIT TESTING? Unit tests find problems early in the development cycle (TDD & BDD) Refactoring Documentation design Integration Better
  4. 4. IS UNIT TESTING A GOOD INVESTMENT? Might slow down the development process. The tests may share the same blind spots with the code. Proving that components X and Y both work independently doesn’t prove that they’re compatible with one another or configured correctly.
  5. 5. TEST DRIVEN DEVELOPMENT(TDD) Test-driven development is related to the test-first programming concepts of extreme programming (XP). TDD is a software development process that relies on the repetition of short development cycle shown on the screen to the left. Behavior-driven development(BDD) based on TDD…
  6. 6. ALRIGHT, SO WHAT IS BDD YOU ASK? Behavior-driven development (BDD) isn't anything new or revolutionary. It's just TDD with any test-related terminology replaced by examples-of-behavior-related terminology: TDD term BDD term Test Example Assertion Expectation assert should, expect Unit Behavior Verification Specification
  7. 7. ASSERTION In simple words, the goal of assertion is to forcefully define if the test fails or passes. Example #1: Statement Passes(True) Fails(False) x = 1; assert (x > 0) assert (x < 0) x++; assert (x > 1) assert (x < 1)
  8. 8. ASSERTION: EXAMPLE Example(Chai) #2: Given the function initialize(): function initialize() { //… Some code goes here … // The initialization went successfully. return true; } Check that function initialize() returns true when called. var isInitialized = initialize(); TDD syntax BDD syntax assert.isTrue(isInitialized) expect(isInitialized)
  9. 9. FIXTURE A test fixture is a fixed state of the software under test used as a baseline for running tests. In JavaScript: simulate AJAX responses; loading known set of data, such as html objects. Example(Jasmine): Require the piece of markup stored in myfixturemarkup.html file before each test: beforeEach(function() { loadFixtures('myfixturemarkup.html'); });
  10. 10. STUB Method stubs are functions with pre-programmed behavior. Example (Sinon): Forcing a method to throw an error in order to test error handling. var fn = foo.stub().throws(Error); expect(fn).to.throw(Error);
  11. 11. SPY A test spy is a function that records arguments, return value, the value of this and exception thrown (if any) for all its calls. Example(Sinon): Test that a function cursor.hide() has been only called once, and only once. sinon.spy(cursor, "hide"); TDD sinon.assert.calledOnce(cursor.hide) BDD expect(cursor.hide.calledOnce)
  12. 12. MOCK  Mocks are fake objects with pre-programmed behavior (like stubs) and pre-programmed expectations. They are like both stubs and spies – in one.  Mocks isolate the imitate the dependency and thus isolate the unit test.
  13. 13. MOCK: EXAMPLE Example(Sinon): Create an expectation that jQuery.each is called once, and only once, and also instructs the mock to behave as we pre-define. var mock = sinon.mock(jQuery); #1 – which method?(“jQuery.each”) #2 – how many times it is called?(only once) #3 – what are the arguments when the method called? (1, {}) #4 – what the method returns? (empty object)
  14. 14. BASIC STRUCTURE #1. Setup/BeforeEach/Before #2. Prepare an input #3. Call a method #4. Check an output #5. Tear down/AfterEach/After
  15. 15. BASIC STRUCTURE EXPLAINED #1. Setup/BeforeEach/Before. before(function(done) { // Create a basic document. document = jsdom.jsdom(); window done(); }); = document.parentWindow;
  16. 16. BASIC STRUCTURE EXPLAINED before(function() { console.log(‘before test’); }); test(‘first test', function() { console.log(‘first test’); }); test(‘second test', function() { console.log(‘second test’); }); afterEach(function() { console.log(‘after each test’); }); Result: before test first test after each test second test after each test
  17. 17. BASIC STRUCTURE EXPLAINED it('should not initialize cursor if zoom level <= minimum zoom level.', function(done) { #2. Prepare an input and predicted result. var zoomLevel = 1; var expectedCursor = {‘color’: ‘white’, ‘height’: #3. Call a method. var actualCursor = cursor.init(zoomLevel); #4. Check an output. expect(actualCursor).to.deep.equal(expectedCursor); done(); }); ‘32px’, etc…};
  18. 18. BASIC STRUCTURE EXPLAINED #5. Tear down/AfterEach/After. after(function(done) { // Remove global objects document. document = null; window done(); }); = null;
  19. 19. OUTPUT: SUCCESS <testsuite name="Macchiato Tests" tests="13" failures="0" errors="0" skipped="0" timestamp="Mon, 02 Dec 2013 11:08:09 GMT" time="0.114"> <testcase classname=‚cursor #init ()" name="should not initialize cursor if zoom level &lt; minimum zoom level.‛ time="0.004"/> </testsuite>
  20. 20. OUTPUT: FAILURE <failure classname="cursor #init()" name="should not initialize cursor if zoom level &lt; minimum zoom level." time="0" message="Cannot read property 'show' of undefined"><![CDATA[TypeError: Cannot read property 'show' of undefined // ..... Exception Stack Trace ..... </failure>
  21. 21. TOOLS No framework Known frameworks:  qUnit(TDD)  Jasmine(BDD)  Mocha+ Chai(TDD & BDD)+ Sinon  Etc…
  22. 22. TOOLS What we use:  Run UT: Mocha  Run UT in parallel: Macchiato  Assert/Expect: Chai  W3C DOM in JavaScript: Jsdom  Mock, spy, stub: Sinon  Code coverage tool: None
  23. 23. UNIT TESTING SPECIFICS IN JAVASCRIPT Stubbing jQuery plugin functions(mock jQuery.fn) Testing Ajax requests Stub jQuery.ajax Fake XMLHttpRequest(XMLHTTP ActiveXObject) Fake server Mocking DOM elements Load fake data via “fixtures” Use W3C Javascript implementation Jsdom
  24. 24. BEST PRACTICES Fast Isolated Consistent Responsibility Self-descriptive No exception Handling Use assertions when needed
  25. 25. Senior Frontend Developer at GlobalLogic Co-founder of IT company DA-14 Contributor of HoganJs, Backbone.Validations akhabibullina _khabibullina