iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 12
1
Modern Web

Vue 怎麼寫測試系列 第 12

Day 12. 實作一個 reddit - 貼文列表

首先,我想先實作一個貼文的列表

<template>
  <div></div>
</template>

<script>
  export default {
    name: 'board',
  }
</script>

<style scoped>

</style>

然後開始寫一點測試

describe('Board.vue', () => {
  let wrapper

  beforeEach(() => {
    wrapper = mount(Board)
  })

  it('should have a name', () => {
    expect(wrapper.name()).toEqual('board')
  })
})

再來我期待這個元件要能印出文章的標題,先來印個一篇吧

it('should have a post title and author', () => {
    wrapper.setData({
      posts: [
        {
          title: 'the title.',
          author: 'author1'
        }
      ]
    })

    expect(wrapper.find('.post').html()).toContain('the title.')
    expect(wrapper.find('.post').html()).toContain('author1')
})

再來不只要有一篇
還要有很多篇

it('should have a lot of posts', () => {
    wrapper.setData({
      posts: [
        { title: 'the title.',  author: 'author1'},
        { title: 'the title2.',  author: 'author2'},
        { title: 'the title3.',  author: 'author3'},
      ]
    })

    expect(wrapper.find('.post:nth-child(2)').html()).toContain('the title2.')
    expect(wrapper.find('.post:nth-child(2)').html()).toContain('author2')
    expect(wrapper.find('.post:nth-child(3)').html()).toContain('the title3.')
    expect(wrapper.find('.post:nth-child(3)').html()).toContain('author3')
})

寫點 helper function 好了

let see = (content, selector) => {
    let wrap = selector ? wrapper.find(selector) : wrapper;

    expect(wrap.html()).toContain(content)
}

乾淨許多。

it('should have a lot of posts', () => {
    wrapper.setData({
      posts: [
        { title: 'the title.',  author: 'author1'},
        { title: 'the title2.',  author: 'author2'},
        { title: 'the title3.',  author: 'author3'},
      ]
    })
    
    see('the title2.', '.post:nth-child(2)')
    see('author2', '.post:nth-child(2)')
    see('the title3.', '.post:nth-child(3)')
    see('author3', '.post:nth-child(3)')
})

然後應該要有個文章的縮圖

it('should have a thumbnail in post', () => {
    wrapper.setData({
      posts: [
        { title: 'the title.',  author: 'author1', thumbnail: 'sample.jpg'},
      ]
    })

    expect(wrapper.find('.post .thumbnail').element.src).toEqual("sample.jpg");
})

// 除此之外,順便測試沒圖片會有什麼相對應的結果。
it('should have a placeholder if post has no thumber', () => {
    wrapper.setData({
      posts: [
        { title: 'the title.',  author: 'author1', thumbnail: ''},
      ]
    })
    expect(wrapper.find('.post .thumbnail').element.src).toEqual("placeholder.jpg");
})

好難閱讀,再加上一點 refactor 吧。
把變數都整理到最上方

posts = [
    {title: 'the title.', author: 'author1', thumbnail: 'sample.jpg'},
    {title: 'the title2.', author: 'author2', thumbnail: ''},
    {title: 'the title3.', author: 'author3', thumbnail: ''},
]

然後多寫一個 helper function 用來檢查圖片。

let picture = (name, selector) => {
    let wrap = selector ? wrapper.find(selector) : wrapper

    expect(wrap.element.src).toContain(name)
}

這樣就乾淨許多

it('should have a thumbnail in post', () => {
    picture('sample.jpg', '.post .thumbnail')
})

it('should have a placeholder if post has no thumbnail', () => {
    picture('placeholder.jpg', '.post:nth-child(2) .thumbnail')
})

最後來測試看看按按鈕能不能 toggle 文章內容

  it('should use show button to toggle content section', () => {
    let postContent = '.post .content'
    let showButton = '.post .show-btn'

    notContain(postContent)
    click(showButton)
    contain(postContent)
    click(showButton)
    notContain(postContent)
  })
  
  let click = (selector) => {
    wrapper.find(selector).trigger('click')
  }

  let contain = (selector) => {
    expect(wrapper.contains(selector)).toBe(true);
  }

  let notContain = (selector) => {
    expect(wrapper.contains(selector)).toBe(false);
  }

今天實在太忙,加上上面的基礎都有講過
影片且等我後續補上。


上一篇
Day 11. 實作一個 reddit - 專案建置
下一篇
Day 13. 插播一個工具問題:vue import 圖片
系列文
Vue 怎麼寫測試30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言