Angular JS Book: Chapter 3: Organización de proyecto

[Fuente: Angular JS Ebook Chapter 3]

Te recomendamos iniciar tu proyecto con Yeoman, con el que te creas la estructura básica para iniciar una aplicación AngularJS.

Los ficheros de una aplicación se pueden clasificar en las siguientes categorías:

Ficheros fuente JS

Take a look at the app/scripts folder. This is where all your JS source code lives. One main file (app/scripts/app.js) will set up the the Angular module and the routes for your application.

In addition, there is a separate folder—app/scripts/controller—which houses the individual controllers. Controllers provide the action and publish data to the scope which will then be displayed in the view. Usually, they correspond one to one with the view.

Directives, filters, and services can also be found under app/scripts, either as complete files (directives.js, filters.js, services.js), or individually, if they are nice and complex.

HTML Angular template files

Now, every AngularJS partial template that Yeoman creates can be found in the app/views folder. This will mirror our app/scripts/controller folder for the most part.

There is one other important Angular template file, which is the main app/index.html. This is responsible for sourcing the AngularJS source files, as well as any source files you create for your application.If you end up creating a new JS file, ensure that you add it to the index.html, and also update the main module and the routes (Yeoman does this for you as well!).

JS library dependencies

Yeoman provides you the app/scripts/vendor folder for all JS source dependencies.Want to use Underscore or SocketIO in your application? No problem—add the dependency to the vendor folder (and your index.html!) and start referencing it in your application.

Static resources

You are creating an HTML application in the end, and it is a given that you will have CSS and image dependencies that you need served as part of your application.

The app/styles and app/img folders are for this very purpose. Just add what you need and start referring to them (with the correct relative paths, of course!) in your application.

Yeoman does not create the app/img path by default.

Unit tests

Testing is super important, and totally effortless when it comes to AngularJS. The
test/spec folder should mirror your app/scripts in terms of tests. Each file should
have a mirror spec file which has its unit tests. The seed creates a stub for each
controller file, under test/spec/controllers, with the same name as the original controller.
These are Jasmine-style specs, which describe a specification for each expected
behavior of the controller.

Integration tests

AngularJS comes with end-to-end testing support built right into the library. All
your E2E tests, in the form of Jasmine specs, are saved under the folder tests/e2e.
Yeoman does not create the tests/folder by default.

While the E2E tests might look like Jasmine, they are not. They are
functions that are executed asynchronously, in the future, by the
Angular Scenario Runner. So don’t expect to be able to do stuff like
you would in a normal Jasmine test (like console.log on the value
of a repeater).

There is also a simple HTML file generated that can be opened by itself in a browser
to run the tests manually. Yeoman doesn’t generate the stubs for these yet, but they
follow a similar style to the unit tests.

Configuration files

There are two configuration files needed. The first one, karma.conf.js, is generated
by Yeoman for you and is used to run the unit tests.

The second one, which Yeoman does not generate yet, is the karma.e2e.conf.js. This is used to run the scenario tests.

There is a sample file at the end of this chapter in the RequireJS integration section.
The config details the dependencies and the files to use when running the unit tests
using Karma. By default, it runs the Karma server at port 9876.

You might ask: how do I run my application? What about unit tests? How do I even
write these various pieces that you are talking about?

Don’t worry, young grasshopper, all in due time. In this chapter, we will deal with setting
up your project and development environment so that things can move along at a rapid
pace once we do start churning out some awesome code. What code you write, and how
it hooks together to form your final awesome application, will come in the next few

Testing with AngularJS

We have said it before (even right in this chapter), and we will say it again: testing is
essential, and AngularJS makes it simple to write the right kind of unit and integration
tests. While AngularJS plays nicely with multiple test runners, we strongly believe that
Karma trumps most of them providing the most robust, solid, and insanely fast test
runner for all your needs.


Karma’s main reason for existence is to make your test-driven development (TDD)
workflow simple, fast, and fun. It uses NodeJS and SocketIO (you don’t need to know
what they are, just assume that they are awesome, cool libraries) to allow running your code, and tests in multiple browsers at insanely fast speeds. Go find out more at

TDD: An Intro

Test-driven development, or TDD, is an AGILE methodology that flips the development
lifecycle by ensuring that tests are written first, before the code is implemented, and that
tests drive the development (and are not just used as a validation tool).
The tenets of TDD are simple:

  • Code is written only when there is a failing test that requires the code to pass
  • The bare minimum amount of code is written to ensure that the test passes
  • Duplication is removed at every step
  • Once all tests are passing, the next failing test is added for the next required functionality.

These simple rules ensure that:

  • Your code develops organically, and that every line of code written is purposeful.
  • Your code remains highly modular, cohesive, and reusable (as you need to be able to test it).
  • You provide a comprehensive array of tests to prevent future breakages and bugs.
  • The tests also act as specification, and thus documentation, for future needs and changes.

We at AngularJS have found this to be true, and the entire AngularJS codebase has been developed using TDD. For an uncompiled, dynamic language like JavaScript, we strongly believe that having a good set of unit tests will reduce headaches in the future!
So how do we get this awesomeness that is Karma? Well, first ensure that NodeJS is
installed on your machine. This comes with NPM (Node Package Manager), which
makes it easy to manage and install the thousands of libraries available for NodeJS.
Once you have NodeJS and NPM installed, installing Karma is as easy as running:

sudo npm install -g karma

There you go. You are ready to start Karmaing (I just made that up, please don’t go about using it in real life) in three easy steps!

Getting your config file up

If you used Yeoman to create your app skeleton, then you already have a readymade
Karma config file waiting for you to use. If not, just go ahead and execute the
following command from the base folder of your application directory:

karma init

in your terminal console, and it will generate a dummy config file (karma.conf.js)
for you to edit to your liking, with some pretty standard defaults. You can use that.

Starting the Karma server

Just run the following command:

karma start [optionalPathToConfigFile]

This will start the Karma server on port 9876 (the default, which you can change
by editing the karma.conf.js file from the previous step). While Karma should open
up a browser and capture it automatically, it will print all the instructions needed
to capture another browser in the console. If you are too lazy to do that, just go to
http://localhost:9876 in another browser or device, and you are good to start running
tests in multiple browsers.While Karma can capture the usual browsers automatically, on start (Firefox, Chrome, IE, Opera, and even PhantomJS), it is not limited to just those browsers. Any device on which you can browse to a URL can possibly be a runner for Karma. So if you open up the browser of your iPhone or Android device and browse to http://machinename:9876 (provided it is accessible!), you could potentially run your tests on mobile devices as well.

Running the tests

Execute the following command:

karma run

That’s it. You should get your results printed right in the console where you ran the
command. Easy, isn’t it?
Unit Tests

AngularJS makes it easy to write your unit tests, and supports the Jasmine style of writing tests by default (as does Karma). Jasmine is what we call a behavior-driven development framework, which allows you to write specifications that denote how your code should behave. A sample test in Jasmine might look something like this.

describe("MyController:", function() {
	it("to work correctly", function() {
		var a = 12;
		var b = a;

As you can see, it lends itself to a very readable format, as most of the code that could
be read in plain English. It also provides a very diverse and powerful set of matchers
(like the expect clauses), and of course has the xUnit staples of setUp and tearDowns
(functions that are executed before and after each individual test case).

AngularJS provides some nice mockups, as well as testing functions, to allow you to
create services, controllers, and filters right in your unit tests, as well as mock out
HttpRequests and the like. We will cover this in Chapter 5.

Karma can be integrated with your development workflow to make it easier, as well as
to get faster feedback on the code you have written.

Integration with IDEs
Karma does not have plug-ins (yet!) for all the latest and greatest IDEs, but you
don’t really need any. All you need to do is add a shortcut command to execute
“karma start” and “karma run” from within your IDE. This can usually be done by
adding a simple script to execute, or the actual shell command, depending on your
choice of editor. You should see the results every time it finishes running, of course.

Running tests on every change
This is utopia for many TDD developers: being able to run all their tests, every time
they press save, within a few milliseconds, and get results back quickly. And this
can be done with AngularJS + Karma pretty easily. Turns out, the Karma config file
(remember the karma.conf.js file from before?) has an innocuous-looking flag
named “autoWatch”. Setting it to true tells Karma to run your tests every time the
file it watches (which is your source and test code) changes. And if you do “karma
start” from within your IDE, guess what? The results from the Karma run will be
available right within your IDE. You won’t even need to switch to console or terminal
to figure out what broke!