Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Unit Testing im Frontend - Lightning Talk

Unit Testing im Frontend - Lightning Talk

Slides to my (german) Talk at the Cosee TechTalks.

Mirjam Aulbach

November 29, 2018
Tweet

More Decks by Mirjam Aulbach

Other Decks in Programming

Transcript

  1. "DOES YOUR TEAM WRITE TESTS FOR BACK-END CODE?"1 1 State

    Of The Web Survey, August 2018, https://dev.to/devteam/state-of-the-web-data---call-for-analysis-2o75
  2. "DOES YOUR TEAM WRITE TESTS FOR FRONT-END CODE?"1 1 State

    Of The Web Survey, August 2018, https://dev.to/devteam/state-of-the-web-data---call-for-analysis-2o75
  3. document.addEventListener("DOMContentLoaded", function() { var unformatedSum = document.querySelector(".js-sum").innerHTML; var sumNum =

    unformatedSum.toString().split('').reverse(); var sumFormatted = []; for (var i = 0; i < sumNum.length; i++) { var currNum = sumNum[i]; if (i != 0 && i % 3 == 0) { sumFormatted.push('.'); } sumFormatted.push(currNum); } if (sumFormatted.length > 0) { sumFormatted.reverse(); sumFormatted.push(' Euro'); } var formatedSum = sumFormatted.join(''); document.querySelector(".js-sum").innerHTML = formatedSum; });
  4. document.addEventListener("DOMContentLoaded", function() { var sumElement = document.querySelector(".js-sum") var unformatedSum =

    sumElement.innerHTML; var formatedSum = moneyFormatter(unformatedSum) sumElement.innerHTML = formatedSum; });
  5. function moneyFormatter(sum) { var sumNum = sum.toString().split('').reverse(); var sumFormatted =

    []; for (var i = 0; i < sumNum.length; i++) { var currNum = sumNum[i]; if (i != 0 && i % 3 == 0) { sumFormatted.push('.'); } sumFormatted.push(currNum); } if (sumFormatted.length > 0) { sumFormatted.reverse(); sumFormatted.push(' Euro'); } return sumFormatted.join('') }
  6. function assertEqual(actual, expected) { if (expected === actual) { console.info('[SUCCESS]

    Is ' + expected); } else { console.error('[ERROR] Expected ' + actual + ' to be ' + expected); } } function tests() { assertEqual(formatSum(1), '1 Euro'); assertEqual(formatSum(12), '12 Euro'); assertEqual(formatSum(123), '123 Euro'); assertEqual(formatSum(1234), '1.234 Euro'); assertEqual(formatSum(12345), '12.345 Euro'); assertEqual(formatSum(123456), '123.456 Euro'); assertEqual(formatSum(1234567), '1.234.567 Euro'); }
  7. function registerFormSubmit() { $('body').on('submit', handleFormSubmit); } function handleFormSubmit(event) { const

    submittedButton = $(event.target).find('[type="submit"]'); submittedButton.addClass('disabled'); formProcessingAnimation(submittedButton); } function appendLoadingDots(element) { const loadingDotHtml = '<span class="loading-dot">.</span>'; element.append(loadingDotHtml).append(loadingDotHtml).append(loadingDotHtml); } function formProcessingAnimation(button) { button.addClass('processing'); button.text('Processing'); appendLoadingDots(button); } export default { registerFormSubmit };
  8. describe('register form submit', function() { const registerFormSubmit = formHelpers.registerFormSubmit; let

    testForm = null; beforeEach(function() { testForm = $('<form></form>').append('<button type="submit">Hello</button>'); $('body').append(testForm); registerFormSubmit(); }); afterEach(function() { testForm.remove(); }); it('defines a registerFormSubmit function', function() { expect(typeof registerFormSubmit).toBe('function'); }); it('disables the button on submit', function() { expect(testForm.find('button')).not.toHaveClass('disabled'); testForm.submit(); expect(testForm.find('button')).toHaveClass('disabled'); }); it('adds class "processing" on submit', function() { expect(testForm.find('button')).not.toHaveClass('processing'); testForm.submit(); expect(testForm.find('button')).toHaveClass('processing'); }); it('replaces the button text with "Processing"', function() { expect(testForm.find('button')).toContainText('Hello'); testForm.submit(); expect(testForm.find('button')).toContainText('Processing...'); }); it('adds three dots on submit', function() { expect(testForm.find('button').find('.loading-dot')).toHaveLength(0); testForm.submit(); expect(testForm.find('button').find('.loading-dot')).toHaveLength(3); }); });
  9. const ButtonExternalLink = ({ url, children, primary, secondary, small })

    => { const btnCustomClass = small ? 'btn-custom-small' : 'btn-custom' const primaryClass = primary ? ' btn-primary' : '' const secondaryClass = secondary ? ' btn-secondary' : '' return ( <a className={`btn ${btnCustomClass}${primaryClass}${secondaryClass}`} href={url} > {children} </a> ) } export default ButtonExternalLink
  10. const testUrl = 'http://forum.conferencebuddy.io/' const linkText = 'Test Button Linktext'

    const linkImage = <img src="test.jpg" /> describe('<ButtonExternalLink />', () => { it('renders without errors', () => { expect(() => shallow( <ButtonExternalLink ></ButtonExternalLink> ) ).not.toThrow() }) it('renders without console errors', () => { expect(() => shallow( <ButtonExternalLink>{linkText}</ButtonExternalLink> ) ).not.toConsoleError() }) })
  11. describe('renders a link with an url and the "btn" class',

    () => { const wrapper = shallow( <ButtonExternalLink url={testUrl}>{linkText}</ButtonExternalLink> ) it('renders a link element', () => { expect(wrapper.find('a')).toHaveLength(1) }) it('renders a link with a given url', () => { expect(wrapper.find('a').prop('href')).toEqual(testUrl) }) it('renders a link with a class', () => { expect(wrapper.hasClass('btn')).toBe(true) }) }) describe('renders a link with a given content', () => { it('renders a link with a text as children', () => { const wrapper = shallow( <ButtonExternalLink url={testUrl}>{linkText}</ButtonExternalLink> ) expect(wrapper.text()).toBe(linkText) }) it('renders a link with an image as children', () => { const wrapper = shallow( <ButtonExternalLink url={testUrl}>{linkImage}</ButtonExternalLink> ) expect(wrapper.contains(linkImage)).toBe(true) }) }) describe('can style specific looks "primary" and "secondary"', () => { it('adds a class for style primary', () => { const wrapper = shallow( <ButtonExternalLink url={testUrl} primary> {linkText} </ButtonExternalLink> ) expect(wrapper.hasClass('btn-primary')).toBe(true) expect(wrapper.hasClass('btn-secondary')).toBe(false) }) it('adds a class for style secondary', () => { const wrapper = shallow( <ButtonExternalLink url={testUrl} secondary> {linkText} </ButtonExternalLink> ) expect(wrapper.hasClass('btn-secondary')).toBe(true) expect(wrapper.hasClass('btn-primary')).toBe(false) }) })