我应该在AngularJS中测试什么?

时间:2022-05-23 07:15:02

Nowadays, specially in the angularjs testing world, there are a lot of guides for made different kind of test, like Unit-testing, Midway Testing and E2E Testing, where you can learn how to made those different test to controllers, factories, etc.

如今,特别是在angularjs测试领域,有很多指南用于进行不同类型的测试,如单元测试,中途测试和端到端测试,在这里您可以学习如何对控制器,工厂等进行不同的测试。

The topic is, what should be testable? I can test that my module app have the controllers, directives, successfull logins, check calls to backend, etc. But What i should test?, because you can test all things, and probably its not a good practice making "easy tests".

主题是,什么应该是可测试的?我可以测试我的模块应用程序有控制器,指令,成功登录,检查后端调用等。但我应该测试什么?,因为你可以测试所有的东西,可能它不是一个很好的做法“轻松测试”。

Can someone give me any suggestions? Thank you.

有人可以给我任何建议吗?谢谢。

2 个解决方案

#1


6  

For a general answer you might have a look at this question.

对于一般答案,您可能会看一下这个问题。

Assuming your unit tests for angular are written in Jasmine or something similar, note that Jasmine is geared toward 'Behavior Driven Development'.

假设您对角度的单元测试是用Jasmine或类似的东西编写的,请注意Jasmine适用于“行为驱动开发”。

From this presentation: "Behavior-Driven-Development is about implementing an application by describing its behavior from the perspective of its stakeholders"

从这个演示文稿:“行为驱动 - 开发是关于通过从其利益相关者的角度描述其行为来实现应用程序”

Another good source, but more strict (geared toward TDD or test-driven-development) is Bob Martin's Clean Code. My biggest testing takeaways:

另一个好的来源,但更严格(面向TDD或测试驱动开发)是Bob Martin的清洁代码。我最大的测试要点:

  • Let tests be your documentation
  • 让测试成为您的文档

  • Your tests free you to refactor
  • 您的测试可以让您重构

  • Test close to the user or consumer and work your way inward if needed
  • 测试靠近用户或消费者,并在需要时向内工作

That is to say,

也就是说,

  • comments can get outdated, but unit tests MUST respond to change in order to pass. This is especially relevant if you are writing with respect to specific user scenarios as BDD suggests.
  • 评论可能会过时,但单元测试必须响应变化才能通过。如果您按照BDD的建议撰写特定用户场景,这一点尤其重要。

  • if you think of your tests as a summary of requirements, any time you make code changes for a new feature and run your test suite, you will know instantly whether your code still meets requirements.
  • 如果您将测试视为需求摘要,则只要您对新功能进行代码更改并运行测试套件,您就会立即知道您的代码是否仍符合要求。

  • Private helper methods, return types, and data structures can change frequently. A user or consumer doesn't care about these, only that, for a given set of inputs, they get a certain effect or return.
  • 私有帮助程序方法,返回类型和数据结构可能经常更改。用户或消费者并不关心这些,只有对于给定的一组输入,他们才能获得某种效果或回报。

examples:

As a rough example, suppose you have a requirement for an application that polls weather forecast data for a given city. Your user or client code's requirement could be phrased something like "Given a set of weather data, when I enter a city name I should get 5 days' forecast data". You might then have a test like:

举一个粗略的例子,假设您需要一个轮询特定城市天气预报数据的应用程序。您的用户或客户代码的要求可以是“给定一组天气数据,当我输入城市名称时,我应该获得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);
          }));
      });
      ...

Then suppose you have another requirement that the weather data say something about humidity, e.g "Given a set of weather data, When I enter a city name and day I should get humidity data"

然后假设您有另一个要求,即天气数据说出有关湿度的信息,例如“给定一组天气数据,当我输入城市名称和日期时,我应该得到湿度数据”

      ...
      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);
          }));
      });
      ...

Here we don't really care about the structure of the result, only that it in some way gives a notion of humidity on monday. We don't really care about the insides of weatherService either (e.g. if it gets data from a database, static file, or other web service). You might have something like this instead, but the requirement is still expressed:

在这里,我们并不真正关心结果的结构,只是它在某种程度上给出了星期一湿度的概念。我们并不关心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);
          }));
      });
      ...

The cool thing here is that you can 'code by wishful thinking' -- you create function signatures close to your users and use cases and then fill them in, getting only what you need. AND now if your first requirement changes to say, "Given a set of weather data, when I enter a city name I should get 4 days' forecast data", you must change the test rather than searching for comments, and you will only need to change code that relates to that requirement change.

这里很酷的是你可以“通过一厢情愿的思考” - 你创建靠近你的用户和用例的功能签名,然后填写它们,只获得你需要的东西。现在,如果您的第一个要求更改为“给定一组天气数据,当我输入城市名称时,我应该获得4天的预测数据”,您必须更改测试而不是搜索评论,而您只需要更改与该需求更改相关的代码。

Some of your behaviors may not be explicitly stated by your users. For example, with respect to the example above, an end-user would be less likely than a web service consumer client to say: "Given a set of weather data, When I enter a city name and a fictional day I should get an exception" You'll have to glean that and the test case yourself:

您的某些行为可能未被您的用户明确说明。例如,对于上面的示例,最终用户不太可能比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();
          }));
      });
      ...

#2


1  

You should ideally test everything.

你应该理想地测试一切。

I normally try to write unit-tests before/as I am coding. This is to ensure that code I'm writing meets some some minimum specification - that it gives the outputs I intend it to. Your unit tests should also be run in other sections as a sort of pre-integration test - have I broken something in another part of the code in making this change? In this fashion, unit tests are providing a first gateway into the program.

我通常会在编码前尝试编写单元测试。这是为了确保我写的代码满足一些最小规范 - 它给出了我想要的输出。您的单元测试也应该作为一种预集成测试在其他部分中运行 - 我是否在进行此更改时在代码的另一部分中破坏了某些内容?通过这种方式,单元测试为程序提供了第一个网关。

Note that in writing unit tests, they mean very little to what is experienced by the user. Maybe the site is functionally OK within the theoretically scope of your unit tests, but maybe they, under certain conditions, drastically affect the experience of the users? Maybe one of your features you have added reduces page load speeds? or breaks the UI in some unforeseen way. Your unit tests might not pick up on this.

请注意,在编写单元测试时,它们对用户所体验的内容意义不大。也许该网站在单元测试的理论范围内功能正常,但在某些情况下,它们可能会严重影响用户的体验?也许您添加的功能之一会降低页面加载速度?或以某种无法预料的方式打破用户界面。你的单元测试可能不会对此有所了解。

Year Of Moo has a good overview of different types of angularjs testing here -http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-karma.html

Moo年对这里不同类型的angularjs进行了很好的概述-http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-karma.html

You should also read up on continuous integration testing - this will give you some idea of how large projects test and integrate code to ensure it meets quality guidelines and doesn't break existing code. In large projects, almost everything is expected to have corresponding unit tests.

您还应该阅读持续集成测试 - 这将让您了解大型项目如何测试和集成代码,以确保它符合质量指南并且不会破坏现有代码。在大型项目中,几乎所有东西都应该有相应的单元测试。

Think of testing as a pipeline

将测试视为管道

  • Does it work to the initial design?
  • 它对初始设计有效吗?

  • Does it break any other code?
  • 它会破坏任何其他代码吗?

  • Does it work in the wider context of the application?
  • 它是否适用于更广泛的应用环境?

  • Does it impact the user experience?
  • 它会影响用户体验吗?

Now, if you're trying to prioritise what to test - test anything you think is sufficiently complicated with unit tests, and try to write E2E test scenarios that cover as much as possible. If you find your E2E tests are failing a lot, that would be a hint that you need more unit tests, because your uncovering a lot of edge cases/undefined behaviour that you may not be aware of.

现在,如果您正在尝试优先考虑测试内容 - 测试您认为单元测试过于复杂的任何内容,并尝试编写尽可能多的E2E测试场景。如果你发现你的E2E测试失败很多,那就暗示你需要更多的单元测试,因为你发现了许多你可能不知道的边缘情况/未定义的行为。

You should definitely be writing unit tests for controllers and directives, as they form the lions share of your application and usually define your business logic.

您肯定应该为控制器和指令编写单元测试,因为它们构成了应用程序的狮子共享,并且通常定义您的业务逻辑。

#1


6  

For a general answer you might have a look at this question.

对于一般答案,您可能会看一下这个问题。

Assuming your unit tests for angular are written in Jasmine or something similar, note that Jasmine is geared toward 'Behavior Driven Development'.

假设您对角度的单元测试是用Jasmine或类似的东西编写的,请注意Jasmine适用于“行为驱动开发”。

From this presentation: "Behavior-Driven-Development is about implementing an application by describing its behavior from the perspective of its stakeholders"

从这个演示文稿:“行为驱动 - 开发是关于通过从其利益相关者的角度描述其行为来实现应用程序”

Another good source, but more strict (geared toward TDD or test-driven-development) is Bob Martin's Clean Code. My biggest testing takeaways:

另一个好的来源,但更严格(面向TDD或测试驱动开发)是Bob Martin的清洁代码。我最大的测试要点:

  • Let tests be your documentation
  • 让测试成为您的文档

  • Your tests free you to refactor
  • 您的测试可以让您重构

  • Test close to the user or consumer and work your way inward if needed
  • 测试靠近用户或消费者,并在需要时向内工作

That is to say,

也就是说,

  • comments can get outdated, but unit tests MUST respond to change in order to pass. This is especially relevant if you are writing with respect to specific user scenarios as BDD suggests.
  • 评论可能会过时,但单元测试必须响应变化才能通过。如果您按照BDD的建议撰写特定用户场景,这一点尤其重要。

  • if you think of your tests as a summary of requirements, any time you make code changes for a new feature and run your test suite, you will know instantly whether your code still meets requirements.
  • 如果您将测试视为需求摘要,则只要您对新功能进行代码更改并运行测试套件,您就会立即知道您的代码是否仍符合要求。

  • Private helper methods, return types, and data structures can change frequently. A user or consumer doesn't care about these, only that, for a given set of inputs, they get a certain effect or return.
  • 私有帮助程序方法,返回类型和数据结构可能经常更改。用户或消费者并不关心这些,只有对于给定的一组输入,他们才能获得某种效果或回报。

examples:

As a rough example, suppose you have a requirement for an application that polls weather forecast data for a given city. Your user or client code's requirement could be phrased something like "Given a set of weather data, when I enter a city name I should get 5 days' forecast data". You might then have a test like:

举一个粗略的例子,假设您需要一个轮询特定城市天气预报数据的应用程序。您的用户或客户代码的要求可以是“给定一组天气数据,当我输入城市名称时,我应该获得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);
          }));
      });
      ...

Then suppose you have another requirement that the weather data say something about humidity, e.g "Given a set of weather data, When I enter a city name and day I should get humidity data"

然后假设您有另一个要求,即天气数据说出有关湿度的信息,例如“给定一组天气数据,当我输入城市名称和日期时,我应该得到湿度数据”

      ...
      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);
          }));
      });
      ...

Here we don't really care about the structure of the result, only that it in some way gives a notion of humidity on monday. We don't really care about the insides of weatherService either (e.g. if it gets data from a database, static file, or other web service). You might have something like this instead, but the requirement is still expressed:

在这里,我们并不真正关心结果的结构,只是它在某种程度上给出了星期一湿度的概念。我们并不关心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);
          }));
      });
      ...

The cool thing here is that you can 'code by wishful thinking' -- you create function signatures close to your users and use cases and then fill them in, getting only what you need. AND now if your first requirement changes to say, "Given a set of weather data, when I enter a city name I should get 4 days' forecast data", you must change the test rather than searching for comments, and you will only need to change code that relates to that requirement change.

这里很酷的是你可以“通过一厢情愿的思考” - 你创建靠近你的用户和用例的功能签名,然后填写它们,只获得你需要的东西。现在,如果您的第一个要求更改为“给定一组天气数据,当我输入城市名称时,我应该获得4天的预测数据”,您必须更改测试而不是搜索评论,而您只需要更改与该需求更改相关的代码。

Some of your behaviors may not be explicitly stated by your users. For example, with respect to the example above, an end-user would be less likely than a web service consumer client to say: "Given a set of weather data, When I enter a city name and a fictional day I should get an exception" You'll have to glean that and the test case yourself:

您的某些行为可能未被您的用户明确说明。例如,对于上面的示例,最终用户不太可能比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();
          }));
      });
      ...

#2


1  

You should ideally test everything.

你应该理想地测试一切。

I normally try to write unit-tests before/as I am coding. This is to ensure that code I'm writing meets some some minimum specification - that it gives the outputs I intend it to. Your unit tests should also be run in other sections as a sort of pre-integration test - have I broken something in another part of the code in making this change? In this fashion, unit tests are providing a first gateway into the program.

我通常会在编码前尝试编写单元测试。这是为了确保我写的代码满足一些最小规范 - 它给出了我想要的输出。您的单元测试也应该作为一种预集成测试在其他部分中运行 - 我是否在进行此更改时在代码的另一部分中破坏了某些内容?通过这种方式,单元测试为程序提供了第一个网关。

Note that in writing unit tests, they mean very little to what is experienced by the user. Maybe the site is functionally OK within the theoretically scope of your unit tests, but maybe they, under certain conditions, drastically affect the experience of the users? Maybe one of your features you have added reduces page load speeds? or breaks the UI in some unforeseen way. Your unit tests might not pick up on this.

请注意,在编写单元测试时,它们对用户所体验的内容意义不大。也许该网站在单元测试的理论范围内功能正常,但在某些情况下,它们可能会严重影响用户的体验?也许您添加的功能之一会降低页面加载速度?或以某种无法预料的方式打破用户界面。你的单元测试可能不会对此有所了解。

Year Of Moo has a good overview of different types of angularjs testing here -http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-karma.html

Moo年对这里不同类型的angularjs进行了很好的概述-http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-karma.html

You should also read up on continuous integration testing - this will give you some idea of how large projects test and integrate code to ensure it meets quality guidelines and doesn't break existing code. In large projects, almost everything is expected to have corresponding unit tests.

您还应该阅读持续集成测试 - 这将让您了解大型项目如何测试和集成代码,以确保它符合质量指南并且不会破坏现有代码。在大型项目中,几乎所有东西都应该有相应的单元测试。

Think of testing as a pipeline

将测试视为管道

  • Does it work to the initial design?
  • 它对初始设计有效吗?

  • Does it break any other code?
  • 它会破坏任何其他代码吗?

  • Does it work in the wider context of the application?
  • 它是否适用于更广泛的应用环境?

  • Does it impact the user experience?
  • 它会影响用户体验吗?

Now, if you're trying to prioritise what to test - test anything you think is sufficiently complicated with unit tests, and try to write E2E test scenarios that cover as much as possible. If you find your E2E tests are failing a lot, that would be a hint that you need more unit tests, because your uncovering a lot of edge cases/undefined behaviour that you may not be aware of.

现在,如果您正在尝试优先考虑测试内容 - 测试您认为单元测试过于复杂的任何内容,并尝试编写尽可能多的E2E测试场景。如果你发现你的E2E测试失败很多,那就暗示你需要更多的单元测试,因为你发现了许多你可能不知道的边缘情况/未定义的行为。

You should definitely be writing unit tests for controllers and directives, as they form the lions share of your application and usually define your business logic.

您肯定应该为控制器和指令编写单元测试,因为它们构成了应用程序的狮子共享,并且通常定义您的业务逻辑。