{"push_id":823204385,"size":6,"distinct_size":6,"ref":"refs/heads/master","head":"5ee5c0a82e2551468cd7d2bc92d935b3d523aef3","before":"b9911b0ef0a9ffe0aca730fa6896e06df456a523","commits":[{"sha":"526d913e1c6a1cc90bfb69098dc9927a134bead8","author":{"email":"f3e731dfa293c7a83119d8aacfa41b5d2d780be9@kreeftmeijer.nl","name":"Jeff Kreeftmeijer"},"message":"Generate a Phoenix 1.0.3 application\n\nIn a freshly generated application, let's run `mix test` at the root of the project. (Please see the [Up and Running Guide](http://www.phoenixframework.org/docs/up-and-running) for instructions on generating a new application.)\n\n    $ mix test\n    ....\n\n    Finished in 0.2 seconds (0.2s on load, 0.00s on tests)\n    4 tests, 0 failures\n\nWe already have four tests!\n\nIn fact, we already have a directory structure completely set up for testing, including a test helper and support files.\n\n> Note: We didn't need to create or migrate our test database because the test helper took care of all that for us.\n\n    # $ tree test\n    test\n    ├── channels\n    ├── controllers\n    │   └── page_controller_test.exs\n    ├── models\n    ├── support\n    │   ├── channel_case.ex\n    │   ├── conn_case.ex\n    │   └── model_case.ex\n    ├── test_helper.exs\n    └── views\n        ├── error_view_test.exs\n        ├── layout_view_test.exs\n        └── page_view_test.exs\n\nThe test cases we get for free include `test/controllers/page_controller_test.exs`, `test/views/error_view_test.exs`, and `test/views/page_view_test.exs`. Nice.\n\nWe're going to look at test cases in detail throughout the testing guides, but let's take a quick look at these three, just to get our feet wet.\n\nThe first test case we'll look at is `test/controllers/page_controller_test.exs`.\n\n    # test/controllers/page_controller_test.exs\n    defmodule HelloPhoenix.PageControllerTest do\n      use HelloPhoenix.ConnCase\n\n      test \"GET /\" do\n        conn = get conn(), \"/\"\n        assert html_response(conn, 200) =~ \"Welcome to Phoenix!\"\n      end\n    end\n\nThere are a couple of interesting things happening here.\n\nThe `get/2` function gives us a connection struct set up as if it had been used for a get request to \"/\". This saves us a considerable amount of tedious setup.\n\nThe assertion actually tests three things - that we got an HTML response (by checking for a content-type of \"text/html\"), that our response code was 200, and that the body of our response matched the string \"Welcome to Phoenix!\"\n\nThe error view test case, `test/views/error_view_test.exs`, illustrates a few interesting things of its own.\n\n    # test/views/error_view_test.exs\n    defmodule HelloPhoenix.ErrorViewTest do\n      use HelloPhoenix.ConnCase, async: true\n\n      # Bring render/3 and render_to_string/3 for testing custom views\n      import Phoenix.View\n\n      test \"renders 404.html\" do\n        assert render_to_string(HelloPhoenix.ErrorView, \"404.html\", []) ==\n               \"Page not found\"\n      end\n\n      test \"render 500.html\" do\n        assert render_to_string(HelloPhoenix.ErrorView, \"500.html\", []) ==\n               \"Server internal error\"\n      end\n\n      test \"render any other\" do\n        assert render_to_string(HelloPhoenix.ErrorView, \"505.html\", []) ==\n               \"Server internal error\"\n      end\n    end\n\n`HelloPhoenix.ErrorViewTest` sets `async: true` which means that each individual test will run in parallel, greatly speeding up the test run. This works because none of the tests access any resources which share state, such as a database. If we set `async: true` for a test case which does access a database, different test processes might modify the same data, corrupting the test results.\n\nIt also imports `Phoenix.View` in order to use the `render_to_string/3` function. With that, all the assertions can be simple string equality tests.\n\nThe page view case, `test/views/page_view_test.exs`, does not contain any tests by default, but it is here for us when we need to add functions to our `HelloPhoenix.PageView` module.\n\n    # test/views/page_view_test.exs\n    defmodule HelloPhoenix.PageViewTest do\n      use HelloPhoenix.ConnCase, async: true\n    end\n\nLet's also take a look at the support and helper files Phoenix provides us.\n\nThe default test helper file, `test/test_helper.exs`, creates and migrates our test database for us. It also starts a transaction for each test to run in. This will \"clean\" the database by rolling back the transaction as each test completes.\n\nThe test helper can also hold any testing-specific configuration our application might need.\n\n    # test/test_helper.exs\n    ExUnit.start\n\n    Mix.Task.run \"ecto.create\", [\"--quiet\"]\n    Mix.Task.run \"ecto.migrate\", [\"--quiet\"]\n    Ecto.Adapters.SQL.begin_test_transaction(HelloPhoenix.Repo)\n\nThe files in `test/support` are there to help us get our modules into a testable state. They provide convenience functions for tasks like setting up a connection struct and finding errors on an Ecto changeset. We'll take a closer look at them in action throughout the rest of the testing guides.\n\n### Running Tests\n\nNow that we have an idea what our tests are doing, let's look at different ways to run them.\n\nAs we saw near the beginning of this guide, we can run our entire suite of tests with `mix test`.\n\n    $ mix test\n    ....\n\n    Finished in 0.2 seconds (0.1s on load, 0.03s on tests)\n    4 tests, 0 failures\n\n    Randomized with seed 540755\n\nIf we would like to run all the tests in a given directory, `test/controllers` for instance, we can pass the path to that directory to `mix test`.\n\n    $ mix test test/controllers/\n    .\n\n    Finished in 0.2 seconds (0.1s on load, 0.04s on tests)\n    1 tests, 0 failures\n\n    Randomized with seed 652376\n\nIn order to run all the tests in a specific file, we can pass the path to that file into `mix test`.\n\n    $ mix test test/views/error_view_test.exs\n    ...\n\n    Finished in 0.2 seconds (0.2s on load, 0.00s on tests)\n    3 tests, 0 failures\n\n    Randomized with seed 220535\n\nAnd we can run a single test in a file by appending a colon and a line number to the filename.\n\nLet's say we only wanted to run the test for the way `HelloPhoenix.ErrorView` renders `500.html`. The test begins on line 12 of the file, so this is how we would do it.\n\n    $ mix test test/views/error_view_test.exs:12\n    Including tags: [line: \"12\"]\n    Excluding tags: [:test]\n\n    .\n\n    Finished in 0.1 seconds (0.1s on load, 0.00s on tests)\n    1 tests, 0 failures\n\n    Randomized with seed 288117\n\nWe chose to run this specifying the first line of the test, but actually, any line of that test will do. These line numbers would all work - `:13`, `:14`, or `:15`.","distinct":true,"url":"https://api.github.com/repos/jeffkreeftmeijer/phoenix_testing_example/commits/526d913e1c6a1cc90bfb69098dc9927a134bead8"},{"sha":"0120a12e8adce88495db0d02cc34ffd23e018bc8","author":{"email":"f3e731dfa293c7a83119d8aacfa41b5d2d780be9@kreeftmeijer.nl","name":"Jeff Kreeftmeijer"},"message":"Add `@moduletag :error_view_case` to `ErrorViewTest`\n\n### Running Tests Using Tags\n\nExUnit allows us to tag our tests at the case level or on the individual test level. We can then choose to run only the tests with a specific tag, or we can exclude tests with that tag and run everything else.\n\nLet's experiment with how this works.\n\nFirst, we'll add a `@moduletag` to `test/views/error_view_test.exs`.\n\n    # test/views/error_view_test.exs\n    defmodule HelloPhoenix.ErrorViewTest do\n      use HelloPhoenix.ConnCase, async: true\n\n      @moduletag :error_view_case\n      ...\n    end\n\nIf we use only an atom for our module tag, ExUnit assumes that it has a value of `true`. We could also specify a different value if we wanted.\n\n    # test/views/error_view_test.exs\n    defmodule HelloPhoenix.ErrorViewTest do\n      use HelloPhoenix.ConnCase, async: true\n\n      @moduletag error_view_case: \"some_interesting_value\"\n      ...\n    end\n\nFor now, let's leave it as a simple atom `@moduletag :error_view_case`.\n\nWe can run only the tests from the error view case by passing `--only error_view_case` into `mix test`.\n\n    $ mix test --only error_view_case\n    Including tags: [:error_view_case]\n    Excluding tags: [:test]\n\n    ...\n\n    Finished in 0.1 seconds (0.1s on load, 0.00s on tests)\n    3 tests, 0 failures\n\n    Randomized with seed 125659\n\n> Note: ExUnit tells us exactly which tags it is including and excluding for each test run. If we look back to the previous section on running tests, we'll see that line numbers specified for individual tests are actually treated as tags.\n\n    $ mix test test/views/error_view_test.exs:12\n    Including tags: [line: \"12\"]\n    Excluding tags: [:test]\n\n    .\n\n    Finished in 0.2 seconds (0.2s on load, 0.00s on tests)\n    1 tests, 0 failures\n\n    Randomized with seed 364723\n\nSpecifying a value of `true` for `error_view_case` yields the same results.\n\n    $ mix test --only error_view_case:true\n    Including tags: [error_view_case: \"true\"]\n    Excluding tags: [:test]\n\n    ...\n\n    Finished in 0.1 seconds (0.1s on load, 0.00s on tests)\n    3 tests, 0 failures\n\n    Randomized with seed 833356\n\nSpecifying `false` as the value for `error_view_case`, however, will not run any tests because no tags in our system match `error_view_case: false`.\n\n    $ mix test --only error_view_case:false\n    Including tags: [error_view_case: \"false\"]\n    Excluding tags: [:test]\n\n    Finished in 0.1 seconds (0.1s on load, 0.00s on tests)\n    0 tests, 0 failures\n\n    Randomized with seed 622422\n\nWe can use the `--exclude` flag in a similar way. This will run all of the tests except those in the error view case.\n\n    $ mix test --exclude error_view_case\n    Excluding tags: [:error_view_case]\n\n    .\n\n    Finished in 0.2 seconds (0.1s on load, 0.03s on tests)\n    1 tests, 0 failures\n\n    Randomized with seed 682868\n\nSpecifying values for a tag works the same way for `--exclude` as it does for `--only`.","distinct":true,"url":"https://api.github.com/repos/jeffkreeftmeijer/phoenix_testing_example/commits/0120a12e8adce88495db0d02cc34ffd23e018bc8"},{"sha":"34a56880b0d25376b2752ac0f59f7eb754398c4f","author":{"email":"f3e731dfa293c7a83119d8aacfa41b5d2d780be9@kreeftmeijer.nl","name":"Jeff Kreeftmeijer"},"message":"Add two tags to `HelloPhoenix.ErrorViewTest`\n\nWe can tag individual tests as well as full test cases. Let's tag a few\ntags in the error view case to see how this works.\n\n    # test/views/error_view_test.exs\n    defmodule HelloPhoenix.ErrorViewTest do\n      use HelloPhoenix.ConnCase, async: true\n\n      @moduletag :error_view_case\n\n      # Bring render/3 and render_to_string/3 for testing custom views\n      import Phoenix.View\n\n      @tag individual_test: \"yup\"\n      test \"renders 404.html\" do\n        assert render_to_string(HelloPhoenix.ErrorView, \"404.html\", []) ==\n               \"Page not found\"\n      end\n\n      @tag individual_test: \"nope\"\n      test \"render 500.html\" do\n        assert render_to_string(HelloPhoenix.ErrorView, \"500.html\", []) ==\n               \"Server internal error\"\n      end\n      ...\n    end\n\nIf we would like to run only tests tagged as `individual_test`,\nregardless of their value, this will work.\n\n    $ mix test --only individual_test\n    Including tags: [:individual_test]\n    Excluding tags: [:test]\n\n    ..\n\n    Finished in 0.1 seconds (0.1s on load, 0.00s on tests)\n    2 tests, 0 failures\n\n    Randomized with seed 813729\n\nWe can also specify a value and run only tests with that.\n\n    $ mix test --only individual_test:yup\n    Including tags: [individual_test: \"yup\"]\n    Excluding tags: [:test]\n\n    .\n\n    Finished in 0.1 seconds (0.1s on load, 0.00s on tests)\n    1 tests, 0 failures\n\n    Randomized with seed 770938\n\nSimilarly, we can run all tests except for those tagged with a given value.\n\n    $ mix test --exclude individual_test:nope\n    Excluding tags: [individual_test: \"nope\"]\n\n    ...\n\n    Finished in 0.2 seconds (0.1s on load, 0.03s on tests)\n    3 tests, 0 failures\n\n    Randomized with seed 539324\n\nHere's an interesting case, let's exclude all of the tests from the error view case except the ones tagged with `individual_test`.\n\n    $ mix test --exclude error_view_case --include individual_test\n    Including tags: [:individual_test]\n    Excluding tags: [:error_view_case]\n\n    ...\n\n    Finished in 0.2 seconds (0.1s on load, 0.03s on tests)\n    3 tests, 0 failures\n\n    Randomized with seed 41241\n\nThis runs the two tests tagged with `individual_test` as well as the one from `test/controllers/page_controller_test.exs`.\n\nWe can be more specific and exclude all the tests from the error view case except the one tagged with `individual_test` that has the value \"yup\".\n\n    $ mix test --exclude error_view_case --include individual_test:yup\n    Including tags: [individual_test: \"yup\"]\n    Excluding tags: [:error_view_case]\n\n    ..\n\n    Finished in 0.2 seconds (0.1s on load, 0.03s on tests)\n    2 tests, 0 failures\n\n    Randomized with seed 61472","distinct":true,"url":"https://api.github.com/repos/jeffkreeftmeijer/phoenix_testing_example/commits/34a56880b0d25376b2752ac0f59f7eb754398c4f"},{"sha":"9b75249103688db1322d7528002ee80308cf54ce","author":{"email":"f3e731dfa293c7a83119d8aacfa41b5d2d780be9@kreeftmeijer.nl","name":"Jeff Kreeftmeijer"},"message":"Exclude `error_view_case: true` from `test_helper.exs`\n\nFinally, we can configure ExUnit to exclude tags by default. Let's\nconfigure it to always exclude tests with the `error_view_case` tag in\n`test/test_helper.exs`.\n\n    # test/test_helper.exs\n    ExUnit.start\n\n    Mix.Task.run \"ecto.create\", [\"--quiet\"]\n    Mix.Task.run \"ecto.migrate\", [\"--quiet\"]\n    Ecto.Adapters.SQL.begin_test_transaction(HelloPhoenix.Repo)\n\n    ExUnit.configure(exclude: [error_view_case: true])\n\nNow when we run `mix test`, it only runs one spec from our\n`page_controller_test.exs`.\n\n    $ mix test\n    Excluding tags: [error_view_case: true]\n\n    .\n\n    Finished in 0.2 seconds (0.1s on load, 0.03s on tests)\n    1 tests, 0 failures\n\n    Randomized with seed 186055\n\nWe can override this behavior with the `--include` flag, telling\n`mix test` to include tests tagged with `error_view_case`.\n\n    $ mix test --include error_view_case\n    Including tags: [:error_view_case]\n    Excluding tags: [error_view_case: true]\n\n    ....\n\n    Finished in 0.2 seconds (0.1s on load, 0.03s on tests)\n    4 tests, 0 failures\n\n    Randomized with seed 748424","distinct":true,"url":"https://api.github.com/repos/jeffkreeftmeijer/phoenix_testing_example/commits/9b75249103688db1322d7528002ee80308cf54ce"},{"sha":"4b0506afa4df514d8132d412a804c04a60807aef","author":{"email":"f3e731dfa293c7a83119d8aacfa41b5d2d780be9@kreeftmeijer.nl","name":"Jeff Kreeftmeijer"},"message":"Revert \"Exclude `error_view_case: true` from `test_helper.exs`\"\n\n### Randomization\n\nRunning tests in random order is a good way to ensure that our tests are truly isolated. If we notice that we get sporadic failures for a given test, it may be because a previous test changes the state of the system in ways that aren't cleaned up afterward, thereby affecting the tests which follow. Those failures might only present themselves if the tests are run in a specific order.\n\nExUnit, will randomize the order tests run in by default, using an integer to seed the randomization. If we notice that a specific random seed triggers our intermittent failure, we can re-run the tests with that same seed to reliably recreate that test sequence in order to help us figure out what the problem is.\n\n    $ mix test --seed 401472\n    ....\n\n    Finished in 0.2 seconds (0.1s on load, 0.03s on tests)\n    4 tests, 0 failures\n\n    Randomized with seed 401472","distinct":true,"url":"https://api.github.com/repos/jeffkreeftmeijer/phoenix_testing_example/commits/4b0506afa4df514d8132d412a804c04a60807aef"},{"sha":"5ee5c0a82e2551468cd7d2bc92d935b3d523aef3","author":{"email":"f3e731dfa293c7a83119d8aacfa41b5d2d780be9@kreeftmeijer.nl","name":"Jeff Kreeftmeijer"},"message":"Generate a scaffold for a `users` resource\n\n### Generating More Files\n\nWe've seen what Phoenix gives us with a newly generated app. Now let's\nsee what happens when we generate a new HTML resource.\n\nLet's borrow the `users` resource we created in the\n[Ecto Models Guide](http://www.phoenixframework.org/docs/ecto-models).\n\nAt the root of our new application, let's run the `mix phoenix.gen.html`\ntask with the following options.\n\n    $ mix phoenix.gen.html User users name:string email:string bio:string number_of_pets:integer\n\n    ...\n\n    Generated hello_phoenix app\n    * creating priv/repo/migrations/20150519043351_create_user.exs\n    * creating web/models/user.ex\n    * creating test/models/user_test.exs\n    * creating web/controllers/user_controller.ex\n    * creating web/templates/user/edit.html.eex\n    * creating web/templates/user/form.html.eex\n    * creating web/templates/user/index.html.eex\n    * creating web/templates/user/new.html.eex\n    * creating web/templates/user/show.html.eex\n    * creating web/views/user_view.ex\n    * creating test/controllers/user_controller_test.exs\n\n    Add the resource to the proper scope in web/router.ex:\n\n        resources \"/users\", UserController\n\n    and then update your repository by running migrations:\n\n        $ mix ecto.migrate\n\nNow let's follow the directions and add the new resources route to our\n`web/router.ex` file.\n\n    # web/router.ex\n    defmodule HelloPhoenix.Router do\n      use HelloPhoenix.Web, :router\n\n      ...\n\n      scope \"/\", HelloPhoenix do\n        pipe_through :browser # Use the default browser stack\n\n        get \"/\", PageController, :index\n        resources \"/users\", UserController\n      end\n\n      # Other scopes may use custom stacks.\n      # scope \"/api\", HelloPhoenix do\n      #   pipe_through :api\n      # end\n    end\n\nWhen we run `mix test` again, we see that we already have sixteen tests!\n\n    $ mix test\n    Compiled lib/hello_phoenix.ex\n    Compiled web/models/user.ex\n    Compiled web/views/page_view.ex\n    Compiled web/views/layout_view.ex\n    Compiled web/views/error_view.ex\n    Compiled web/controllers/page_controller.ex\n    Compiled web/router.ex\n    Compiled web/controllers/user_controller.ex\n    Compiled web/views/user_view.ex\n    Compiled lib/hello_phoenix/endpoint.ex\n    Generated hello_phoenix app\n    ................\n\n    Finished in 0.5 seconds (0.4s on load, 0.1s on tests)\n    16 tests, 0 failures\n\n    Randomized with seed 537537\n\nAt this point, we are at a great place to transition to the rest of the\ntesting guides, in which we'll examine these tests in much more detail,\nand add some of our own.","distinct":true,"url":"https://api.github.com/repos/jeffkreeftmeijer/phoenix_testing_example/commits/5ee5c0a82e2551468cd7d2bc92d935b3d523aef3"}]}