如今,特别是在angularjs测试领域,有很多指南可用于进行不同类型的测试,如单元测试,中途测试和端到端测试,在这里您可以学习如何对控制器,工厂进行不同的测试等等。
主题是,什么应该是可测试的?我可以测试我的模块应用程序有控制器,指令,成功登录,检查后端调用等。但我应该测试什么?,因为你可以测试所有的东西,可能它不是一个很好的做法“轻松测试”。
有人可以给我任何建议吗?谢谢。
答案 0 :(得分:6)
对于一般性答案,您可以查看此question。
假设您对角度的单元测试是用Jasmine或类似的方式编写的,请注意Jasmine适用于“行为驱动开发”。
来自this presentation: “行为驱动 - 开发是关于通过从利益相关者的角度描述其行为来实现应用程序”
另一个好的来源,但更严格(面向TDD或测试驱动开发)是Bob Martin的清洁代码。我最大的测试要点:
也就是说,
作为一个粗略的例子,假设您需要一个应用程序来轮询给定城市的天气预报数据。您的用户或客户代码的要求可能类似于“给定一组天气数据,当我输入城市名称时,我应该获得5天的预测数据”。然后,您可能会进行如下测试:
describe('Given a set of weather data'....
...
describe('when I enter Los Angeles', function() {
it('should return 5 days of forecast data for Los Angeles',
mocks.inject(function(weatherService) {
var result = weatherService.getForecast('Los Angeles');
expect(result.DayToForecast.lenth).toEqual(5);
}));
});
...
然后假设您有另一个要求,即天气数据会说出有关湿度的信息,例如“给定一组天气数据,当我输入城市名称和日期时,我应该获得湿度数据”
...
describe('When I enter Los Angeles and Monday', function() {
it('should return humidity data for Los Angeles on Monday',
mocks.inject(function(weatherService) {
var result = weatherService.getForecast('Los Angeles');
expect(result.DayToForecast['Monday'].humidity).not.toBe(null);
}));
});
...
这里我们并不关心结果的结构,只是它在某种程度上给出了星期一湿度的概念。我们并不关心weatherService的内部(例如,它是否从数据库,静态文件或其他Web服务获取数据)。你可能会有类似的东西,但仍然表达了要求:
...
describe('when I enter Los Angeles and Monday', function() {
it('should return humidity data for Los Angeles on Monday',
mocks.inject(function(weatherService) {
var result = weatherService.getForecast('Los Angeles','Monday');
expect(result.humidity).not.toBe(null);
}));
});
...
这里很酷的是你可以'通过一厢情愿的思考' - 你创建靠近你的用户和用例的功能签名,然后填写它们,只获得你需要的东西。现在,如果您的第一个要求改变为“给定一组天气数据,当我输入城市名称时,我应该获得4天的预测数据”,您必须更改测试而不是搜索评论,而您只需要更改与该需求变更相关的代码。
您的某些行为可能未被您的用户明确说明。例如,对于上面的示例,最终用户不太可能比Web服务消费者客户端说:“给定一组天气数据,当我输入城市名称和虚构的一天时,我应该得到一个例外“你必须自己收集这个和测试用例:
...
describe('when I enter Los Angeles and EigthDay', function() {
it('should throw an exception',
mocks.inject(function(weatherService) {
var weatherServiceCall = function(){
weatherService.getForecast('Los Angeles','EighthDay');
};
expect(weatherServiceCall).toThrow();
}));
});
...
答案 1 :(得分:1)
理想情况下,你应该测试一切。
我通常会尝试在编码前编写单元测试。这是为了确保我写的代码满足一些最小规范 - 它给出了我想要的输出。您的单元测试也应该作为一种预集成测试在其他部分中运行 - 我是否在进行此更改时在代码的另一部分中破坏了某些内容?通过这种方式,单元测试为程序提供了第一个网关。
请注意,在编写单元测试时,它们对用户体验的内容意义不大。也许该网站在单元测试的理论范围内功能正常,但在某些条件下,它们可能会极大地影响用户的体验?也许您添加的功能之一会降低页面加载速度?或以某种无法预料的方式打破用户界面。你的单元测试可能不会对此有所了解。
Moo年对这里不同类型的angularjs进行了很好的概述 - http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-karma.html
您还应该阅读持续集成测试 - 这将让您了解大型项目如何测试和集成代码,以确保它符合质量指南并且不会破坏现有代码。在大型项目中,几乎所有东西都应该有相应的单元测试。
将测试视为管道
现在,如果您正在尝试优先考虑测试内容 - 测试您认为单元测试过于复杂的任何内容,并尝试编写尽可能多的E2E测试场景。如果你发现你的E2E测试失败很多,那就暗示你需要更多的单元测试,因为你发现了很多你可能不知道的边缘情况/未定义的行为。
您绝对应该为控制器和指令编写单元测试,因为它们构成了应用程序的狮子会共享,并且通常定义您的业务逻辑。