美文网首页
前端自动化测试

前端自动化测试

作者: 强某某 | 来源:发表于2020-06-19 14:21 被阅读0次

    为什么要进行测试

    1. 测试可以确保得到预期的结果
    2. 作为现有代码⾏为的描述
    3. 促使开发者写可测试的代码,⼀般可测试的代码可读性也会⾼⼀点
    4. 如果依赖的组件有修改,受影响的组件能在测试中发现错误

    测试分类

    单元测试:指的是以原件的单元为单位,对软件进⾏测试。单元可以是⼀个函数,也可以是⼀个模块或⼀个组件,基本特征就是只要输⼊不变,必定返回同样的输出。⼀个软件越容易些单元测试,就表明它的模块化结构越好,给模块之间的耦合越弱。React的组件化和函数式编程,天⽣适合进⾏单元测试

    功能测试:相当于是⿊盒测试,测试者不了解程序的内部情况,不需要具备编程语⾔的专⻔知识,只知道程序的输⼊、输出和功能,从⽤户的⻆度针对软件界⾯、功能和外部结构进⾏测试,不考虑内部的逻辑

    集成测试:在单元测试的基础上,将所有模块按照设计要求组装成⼦系统或者系统,进⾏测试

    冒烟测试:在正式全⾯的测试之前,对主要功能进⾏的与测试,确认主要功能是否满⾜需要,软件是否能正常运⾏

    组件的单元测试有很多好处:

    • 提供描述组件⾏为的⽂档
    • 节省⼿动测试的时间
    • 减少研发新特性时产⽣的 bug
    • 改进设计
    • 促进重构
    1.jpg

    测试⼯具

    2.jpg

    单测

    单元测试(unit testing),是指对软件中的最⼩可测试单元进⾏检查和验证。

    在vue中,推荐⽤Mocha+chai 或者jest,咱们使⽤jest演示,语法基本⼀致

    新建kaikeba.spec.js,.spec.js是命名规范,写下⼀下代码

    function add(num1, num2) {
     return num1 + num2
    }
    describe('Kaikeba', () => {
     it('测试加法', () => {
     expect(add(1, 3)).toBe(3)
     expect(add(1, 3)).toBe(4)
     expect(add(-2, 3)).toBe(1)
     })
    })
    

    执⾏ npm run test:unit


    3.jpg

    api介绍

    • describe : 定义⼀个测试套件
    • it :定义⼀个测试⽤例
    • expect :断⾔的判断条件
    • toBe :断⾔的⽐较结果

    测试Vue组件

    <template>
     <div>
     <span>{{ message }}</span>
     <button @click="changeMsg">点击</button>
     </div>
    </template> <script>
     export default {
     data () {
     return {
     message: 'vue-text'
     }
     },
     created () {
     this.message = '开课吧'
     },
     methods:{
     changeMsg(){
     this.message = '按钮点击'
     }
     }
     }
    </script>
    
    // 导⼊ Vue.js 和组件,进⾏测试
    import Vue from 'vue'
    import KaikebaComp from '@/components/Kaikeba.vue'
    // 这⾥是⼀些 Jasmine 2.0 的测试,你也可以使⽤你喜欢的任何断⾔库或测试⼯具。
    describe('KaikebaComp', () => {
     // 检查原始组件选项
     it('由created⽣命周期', () => {
     expect(typeof KaikebaComp.created).toBe('function')
     })
     // 评估原始组件选项中的函数的结果
     it('初始data是vue-text', () => {
     expect(typeof KaikebaComp.data).toBe('function')
     const defaultData = KaikebaComp.data()
     expect(defaultData.message).toBe('hello!')
     })
    })
    
    4.jpg

    检查mounted之后

    it('mount之后测data是开课吧', () => {
     const vm = new Vue(KaikebaComp).$mount()
     expect(vm.message).toBe('开课吧')
     })
    

    用户点击

    和写vue 没啥本质区别,只不过我们⽤测试的⻆度去写代码,vue提供了专⻔针对测试的 @vue/test-utils,可以区官网查看更多API

    it('按钮点击后', () => {
     const wrapper = mount(KaikebaComp)
     wrapper.find('button').trigger('click')
     expect(wrapper.vm.message).toBe('按钮点击')
     // 测试html渲染结果
     expect(wrapper.find('span').html()).toBe('<span>按钮点击</span>')
     })
    

    测试覆盖率

    jest⾃带覆盖率,如果⽤的mocha,需要使⽤istanbul来统计覆盖率
    package.json⾥修改jest配置

    "jest": {
     "collectCoverage": true,
     "collectCoverageFrom": ["src/**/*.{js,vue}"],
     }
    

    在此执⾏npm run test:unit

    5.jpg

    可以看到我们kaikeba.vue的覆盖率是100%,我们修改⼀下代码

    <template>
     <div>
     <span>{{ message }}</span>
     <button @click="changeMsg">点击</button>
     </div>
    </template> <script>
    export default {
     data() {
     return {
     message: "vue-text",
     count: 0
     };
    },
     created() {
     this.message = "开课吧";
     },
     methods: {
     changeMsg() {
     if (this.count > 1) {
     this.message = "count⼤于1";
     } else {
     this.message = "按钮点击";
     }
     },
     changeCount() {
     this.count += 1;
     }
     }
    };
    </script>
    
    6.jpg

    现在的代码,依然是测试没有报错,但是覆盖率只有66%了,⽽且没有覆盖的代码⾏数,都标记了出来

    Jest详解

    beforeAll(() => {
     console.log('global before all');
    });
    afterAll(() => {
     console.log('global after all');
    });
    beforeEach(() =>{
     console.log('global before each');
    });
    afterEach(() => {
     console.log('global after each');
    });
    describe('test1', () => {
     beforeAll(() => {
     console.log('test1 before all');
     });
     
     afterAll(() => {
     console.log('test1 after all');
     });
     
     beforeEach(() => {
     console.log('test1 before each');
     });
     
     afterEach(() => {
     console.log('test1 after each');
     });
     
     it('test sum', () => {
     expect(sum(2, 3)).toEqual(5);
     });
     
     it('test mutil', () => {
     expect(sum(2, 3)).toEqual(7);
     });
     
    });
    

    断言

    1. expect(value):要测试⼀个值进⾏断⾔的时候,要使⽤expect对值进⾏包裹
    2. toBe(value):使⽤Object.is来进⾏⽐较,如果进⾏浮点数的⽐较,要使⽤toBeCloseTo
    3. not:⽤来取反
    4. oEqual(value):⽤于对象的深⽐较
    5. toMatch(regexpOrString):⽤来检查字符串是否匹配,可以是正则表达式或者字符串
    6. toContain(item):⽤来判断item是否在⼀个数组中,也可以⽤于字符串的判断
    7. toBeNull(value):只匹配null
    8. toBeUndefined(value):只匹配undefined
    9. toBeDefined(value):与toBeUndefined相反
    10. toBeTruthy(value):匹配任何使if语句为真的值
    11. toBeFalsy(value):匹配任何使if语句为假的值
    12. toBeGreaterThan(number): ⼤于
    13. toBeGreaterThanOrEqual(number):⼤于等于
    14. toBeLessThan(number):⼩于
    15. toBeLessThanOrEqual(number):⼩于等于
    16. toBeInstanceOf(class):判断是不是class的实例
    17. anything(value):匹配除了null和undefined以外的所有值
    18. resolves:⽤来取出promise为fulfilled时包裹的值,⽀持链式调⽤
    19. rejects:⽤来取出promise为rejected时包裹的值,⽀持链式调⽤
    20. toHaveBeenCalled():⽤来判断mock function是否被调⽤过
    21. toHaveBeenCalledTimes(number):⽤来判断mock function被调⽤的次数
    22. assertions(number):验证在⼀个测试⽤例中有number个断⾔被调⽤
    23. extend(matchers):⾃定义⼀些断⾔

    方法

    1. simulate(event, mock):模拟事件,⽤来触发事件,event为事件名称,mock为⼀个event object
    2. instance():返回组件的实例
    3. find(selector):根据选择器查找节点,selector可以是CSS中的选择器,或者是组件的构造函数,
      组件的display name等
    4. at(index):返回⼀个渲染过的对象
    5. get(index):返回⼀个react node,要测试它,需要重新渲染
    6. contains(nodeOrNodes):当前对象是否包含参数重点 node,参数类型为react对象或对象数组
    7. text():返回当前组件的⽂本内容
    8. html(): 返回当前组件的HTML代码形式
    9. props():返回根组件的所有属性
    10. prop(key):返回根组件的指定属性

    E2E测试

    借⽤浏览器的能⼒,站在⽤户测试⼈员的⻆度,输⼊框,点击按钮等,完全模拟⽤户,这个和具体的框架关系不⼤,完全模拟浏览器⾏为.

    也被称为端到端测试,启动之后会启动一个类似于浏览器的窗口自动执行,因为需求变更等原因,E2E代码测试编码多,甚至可能为了测试一行代码需要写十行测试代码,针对多变的场景不适合,最多针对登录管理等功能固定的页面可以写一些E2E测试。

    对比单元测试:单元测试针对vue甚至可以针对到单一组件,更具象,所以一般只是写单元测试。

    修改e2e/spec/test.js

    // https://docs.cypress.io/api/introduction/api.html
    describe('端到端测试,抢测试⼈员的饭碗', () => {
     it('先访问⼀下', () => {
     cy.visit('/')
     // cy.contains('h1', 'Welcome to Your Vue.js App')
     cy.contains('#message', '开课吧')
     })
    })
    
    7.jpg

    可以看到是打开了⼀个浏览器进⾏测试

    测试⽤户点击

    // https://docs.cypress.io/api/introduction/api.html
    describe('端到端测试,抢测试⼈员的饭碗', () => {
     it('先访问⼀下', () => {
     cy.visit('/')
     // cy.contains('h1', 'Welcome to Your Vue.js App')
     cy.contains('#message', '开课吧')
     cy.get('button').click()
     cy.contains('#message', '按钮点击')
     })
    })
    

    TDD

    所以TDD 就是测试驱动开发模式,就是我们开发⼀个新功能,先把测试写好,然后测试跑起来,会报错,我们再开始写代码,挨个的把测试跑绿,功能也就完成了

    React 自动化测试

    React中,也是使⽤jest来做⾃动化测试

    https://jestjs.io/docs/en/tutorial-react

    总结

    测试会极大拖慢开发进度,但是如果测试一旦也写好。例如单元测试,在package.json文件中配置了,则每次保存或者构建之前都会执行一下测试的函数,例如写了add函数,多成员开发,B修改了该函数,则测试不通过,连项目都跑不起来,则保证了项目的健壮性。

    代码地址:https://gitee.com/zengqiang_455/qianduanzidonghuaceshixiaodemo

    相关文章

      网友评论

          本文标题:前端自动化测试

          本文链接:https://www.haomeiwen.com/subject/waqxzhtx.html