-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.json
1 lines (1 loc) · 28.6 KB
/
index.json
1
[{"content":"In Ruby you have some tricks in the console. I always use the _ to retrieve the last return value. In Elixir, you have the same approach with v function. Let’s see:\n iex help for v function\n As you can see, the function v can get the last value because it’s using the default value -1 or you can use v(line_number) to get the value from a previous one.\n Important: This post was original published by me in https://medium.com/@erichkist/elixir-tips-1-copy-last-result-in-iex-871f148d7f41 on November 09, 2017.\n ","permalink":"https://erichkist.com/elixir-tips-1-copy-last-result-in-iex/","summary":"In Ruby you have some tricks in the console. I always use the _ to retrieve the last return value. In Elixir, you have the same approach with v function. Let’s see:\n iex help for v function\n As you can see, the function v can get the last value because it’s using the default value -1 or you can use v(line_number) to get the value from a previous one.","title":"Elixir tips: #1 — Copy last result in IEX"},{"content":"Today we will continue exploring techniques for debugging and tracing Elixir code that are so important for running and understanding production systems.\n Important: This post was original published by me in http://blog.plataformatec.com.br/2016/05/tracing-and-observing-your-remote-node/ on May 10, 2016.\n In the past, we have discussed:\n how to debug your application how to trace systems with Erlyberly how to use the observer to introspect applications The examples above always connected to systems running locally. Given Elixir’s and the Erlang VM focus on distributed systems, you may have wondered: can we use the VM capabilities to trace and observe remote nodes?\nCertainly!\nYour application runs as part of the Erlang Runtime System, which is often called a node, as it may connect to other machines. Before we establish such connections, let’s get to know some concepts and then configure our applications.\nEPMD Erlang Port Mapper Daemon, EPMD, acts as a name server on all hosts involved in distributed Erlang communications. When an Erlang node starts, the node has a name and it obtains an address from the host OS kernel. The default port the daemon runs on is 4369 but you can change it with the ERL_EPMD_PORT environment variable \nYou can run epmd -names to check the port and the nodes connected:\nuser@localhost:~$ epmd -names epmd: up and running on port 4369 with data: name myapp at port 43316 SSH Port Forwarding Depending on your firewall configuration, the port 4369 from EPMD is blocked by default. We will use port forwarding to redirect our local EPMD port to the remote EPMD with ssh: ssh user@myapp.com -L4369:localhost:4369.\nTherefore, when we start a node locally, it will attempt to register itself to the EPMD running on port 4369, which is effectively forwarded to the remote EPMD. Once our local node registers itself to the remote EPMD, it will be able to find all remote nodes running on the remote EPMD.\nConfiguring the Phoenix application Imagine we want to trace or observe a Phoenix project. In our case, our project was released using exrm and our release path in production has a directory called running-config. In this directory we can find the files sys.config and vm.args.\nThe file vm.args is responsible for configuring our application when it starts. Let’s change it as follows:\n## Name of the node -name myapp@127.0.0.1 -kernel inet_dist_listen_min 9001 inet_dist_listen_max 9001 ## Cookie for distributed erlang (you want a really long cookie) -setcookie my_cookie We added a name to your application, set a port range where remote nodes may connect to and chose a cookie secret. If your server was already running, you will need to restart it after changing vm.args.\nAfter restarting our application, we should see it registered in the remote EPMD:\nuser@localhost:~$ epmd -names epmd: up and running on port 4369 with data: name myapp at port 9001 Tracing application After our application is started, we need to change our ssh command to forward to EPMD and our application ports: ssh user@myapp.com -L4369:localhost:4369 -L9001:localhost:9001.\nNow let’s start the tracing tool locally with the proper cookie options. The tracing tool will register itself to the remote EPMD, via port forwarding, and find our remote application. Once the Erlyberly is started, you should see the following in the remote EPMD:\nuser@localhost:~$ epmd -names epmd: up and running on port 4369 with data: name myapp at port 9001 name erlyberly-1460466831146 at port 54420 Observing application We can also observe a remote system using ssh port forwarding. One option is to establish a remote shell, as explained in the IEx documentation :\n$ iex --name mylocalmachine@127.0.0.1 --cookie my_cookie --remsh myapp@127.0.0.1 Now you are connected directly to a remote node and you can introspect it as well as start tools like Observer.\nAlternatively, you can start a new local shell with the same cookie as the remote node:\n$ iex --name mylocalmachine@127.0.0.1 --cookie my_cookie Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] Interactive Elixir (1.2.4) - press Ctrl+C to exit (type h() ENTER for help) iex(mylocalmachine@127.0.0.1)1\u0026gt; :observer.start() :ok The local shell should be registered in the remote EPMD alongside the remote system:\nuser@localhost:~$ epmd -names epmd: up and running on port 4369 with data: name mylocalmachine at port 50055 name myapp at port 9001 With Observer open, we can now change the inspected node using the menu ‘Nodes \u0026gt; Connect node’. In the prompt we can fill in the node name. In our example the node is myapp@127.0.0.1.\n Observer in action!\n Troubleshooting You may receive an error similar to the one below when you try to connect through Observer:\n16:38:44.278 [error] [node: :\u0026quot;mylocalmachine@127.0.0.1\u0026quot;, call: {:observer_backend, :sys_info, []}, reason: {:badrpc, {:EXIT, {:undef, [{:observer_backend, :sys_info, [], []}, {:rpc, :\u0026quot;-handle_call_call/6-fun-0-\u0026quot;, 5, [file: 'rpc.erl', line: 206]}]}}}] This occurs because the :observer_backend is disabled. You can enable it by adding the :runtime_tools to your application mix.exs file. You can get more details in the Runtime tools documentation .\nDo you use other techniques to connect to remote nodes? Share your tips with a comment below.\n","permalink":"https://erichkist.com/tracing-and-observing-your-remote-node/","summary":"Today we will continue exploring techniques for debugging and tracing Elixir code that are so important for running and understanding production systems.\n Important: This post was original published by me in http://blog.plataformatec.com.br/2016/05/tracing-and-observing-your-remote-node/ on May 10, 2016.\n In the past, we have discussed:\n how to debug your application how to trace systems with Erlyberly how to use the observer to introspect applications The examples above always connected to systems running locally.","title":"Tracing and observing your remote node"},{"content":"At Plataformatec, we are always learning new techniques to help our clients introspect and monitor their production systems. Last week, we saw debugging techniques in Elixir and now we will see one of many ways to do tracing in Elixir.\n Important: This post was original published by me in http://blog.plataformatec.com.br/2016/04/how-to-trace-elixir-nodes-with-erlyberly/ on April 14, 2016.\n For this post, we will use erlyberly . You can see the installation instructions in its README.\nTracing gives you all the data you need and doesn’t block your process as debuggers. It’s indicated for production and development.\n Erlyberly in action!\n Naming nodes After you start erlyberly with java -jar target/erlyberly-\u0026lt;version\u0026gt;-runnable.jar, you need two pieces of information from your application to connect: the target node and its cookie.\nThe target node is how you will identify the node that you want to connect to. You need to start your process with the option --name or --sname (short name).\n$ iex --name \u0026#34;foo@127.0.0.1\u0026#34; -S mix Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] Interactive Elixir (1.2.4) - press Ctrl+C to exit (type h() ENTER for help) iex(foo@127.0.0.1)1\u0026gt; node :\u0026#34;foo@127.0.0.1\u0026#34; The cookie provides authentication for connecting nodes. When you start a node with a name, you will receive a cookie that is created randomly the first time and reused in the next ones. You can check the cookies in IEx with Node.get_cookie/0 or in the file ~/.erlang.cookie.\nYou can start a new node with a different cookie too:\n$ iex --name \u0026#34;foo@127.0.0.1\u0026#34; --cookie \u0026#34;my_cookie\u0026#34; -S mix Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] Interactive Elixir (1.2.4) - press Ctrl+C to exit (type h() ENTER for help) iex(foo@127.0.0.1)1\u0026gt; Node.get_cookie :my_cookie The target and cookie are used to connect remotely to your node. Similar to when we use the User Switch command inside the IEx shell or via the option --remsh when starting IEx.\nErlyberly usage Now we are connected to our application. We have 3 panels: processes, modules and trace log. Furthermore, we can see the Erlang memory and the crash dumps.\nProcesses List of processes from your application\n In the processes area, you can check a snapshot or start polling your application. We have a lot of information about our processes such as their PID, reductions, message queue and head/stack size.\nWith the message queue, we can avoid the most common cause of failure: out of memory in the node. This is usually related to message queues when a process receives messages at a faster pace than it can handle.\nThe CPU is harder to profile. Some examples that we can point out: scheduling and busy looping to ensure the lowest latency. The VM internally uses a model based on reductions (work actions). Every function call will increment the reduction counter for its current process. The process is descheduled after a given number of reductions. We can access this information in the processes area.\nMemory Memory used by Erlang VM\n The memory graph is based on :erlang.memory(). The data is the memory actively used by Erlang VM, not the memory set aside by the OS. You can find information about the processes (stacks and heaps from Erlang), ETS tables, atoms in the VM and the binaries.\nModules and traces Check communication between your functions\n In the modules area, you can filter your modules and check which functions you want to trace and see their source code. In the trace logs, you can check your function calls with breakdown of their arguments and their results.\nYou can check for exceptions, incomplete calls, process states and so on. You can find more information in the erlyberly project.\nThis is one more visual tool for tracing your application. Other options are redbug, recon_trace, dbg and more. Which tools and techniques do you use to introspect your production apps?\n","permalink":"https://erichkist.com/how-to-trace-elixir-nodes-with-erlyberly/","summary":"At Plataformatec, we are always learning new techniques to help our clients introspect and monitor their production systems. Last week, we saw debugging techniques in Elixir and now we will see one of many ways to do tracing in Elixir.\n Important: This post was original published by me in http://blog.plataformatec.com.br/2016/04/how-to-trace-elixir-nodes-with-erlyberly/ on April 14, 2016.\n For this post, we will use erlyberly .","title":"How to trace Elixir nodes with Erlyberly"},{"content":"It’s common that our first experience with debugging in a new language is by printing values to the terminal. Elixir isn’t different: we can use IO.puts/2 and IO.inspect/2. However, Elixir also provides other approaches to debugging.\n Important: This post was original published by me in http://blog.plataformatec.com.br/2016/04/debugging-techniques-in-elixir-lang/ on April 07, 2016.\n In this blog post, we’ll show you other 2 options: IEx.pry/0 and :debugger.\nIEx.pry The name “pry” is an old friend in the Ruby ecosystem but it has a different behavior in Elixir. Let’s create a new project with mix to try it out:\nmix new example cd example Now let’s write some sample code in lib/example.ex:\nrequire IEx; defmodule Example do def double_sum(x, y) do IEx.pry hard_work(x, y) end defp hard_work(x, y) do 2 * (x + y) end end Now start a new IEx session and invoke our new function:\n$ iex -S mix Interactive Elixir (1.2.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)\u0026gt; Example.double_sum(1, 2) IEx.pry/0 is built on top of IEx. Although it isn’t a traditional debugger since you can’t step, add breakpoints and so forth, it’s a good tool for non-production debugging. It runs in the caller process, blocking the caller and allowing us to access its binding (variables), verify its lexical information and access the process information. You can finish your “pry” session by calling respawn, which starts a new IEx shell.\n IEx.pry in action!\n You can find more information at IEx.pry doc .\nDebugger If you need a breakpoint feature, we can use the :debugger module that ships with Erlang. Let’s make a change in our example to be more didactic:\ndefmodule Example do def double_sum(x, y) do hard_work(x, y) end defp hard_work(x, y) do x = 2 * x y = 2 * y x + y end end Now we can start our debugger:\n$ iex -S mix Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] Compiled lib/example.ex Interactive Elixir (1.2.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)\u0026gt; :debugger.start() {:ok, #PID\u0026lt;0.87.0\u0026gt;} iex(2)\u0026gt; :int.ni(Example) {:module, Example} iex(3)\u0026gt; :int.break(Example, 3) :ok iex(4)\u0026gt; Example.double_sum(1,2) When you started the debugger, a Graphical User Interface must have opened in your machine. We called :int.ni(Example) to prepare our module for debugging and then added a breakpoint to line 3 with :int.break(Example, 3). After we call our function, we can see our process with break status in the debugger:\n :debugger in action!\n The process is blocked as in IEx.pry/0. We can add a new breakpoint in the monitor window, inspect the code, see the variables and navigate it in steps.\nDebugger has more options and command instructions that you can use. Take a look at Debbuger doc for more information.\nTroubleshooting You may have some problems when executing :int.ni(Example) in the example above:\niex(2)\u0026gt; :int.ni(Example) ** Invalid beam file or no abstract code: \u0026#39;Elixir.Example\u0026#39; Before the upcoming Erlang 19 version, the debugger did not have the heuristic that traverses the module source attribute applied. If you are not on the latest Erlang version, you can update the debugger manually with the following steps:\n Download the file int.erl from the PR. Compile it with erlc -o . int.erl. Overwrite lib/debugger/ebin/int.beam in your Erlang installation with the new compiled file. In the next post, we will see a tracing technique that doesn’t block the caller process.\nWhat about you? What are the tools that you are using to debug your Elixir applications?\n","permalink":"https://erichkist.com/debugging-techniques-in-elixir-lang/","summary":"It’s common that our first experience with debugging in a new language is by printing values to the terminal. Elixir isn’t different: we can use IO.puts/2 and IO.inspect/2. However, Elixir also provides other approaches to debugging.\n Important: This post was original published by me in http://blog.plataformatec.com.br/2016/04/debugging-techniques-in-elixir-lang/ on April 07, 2016.\n In this blog post, we’ll show you other 2 options: IEx.pry/0 and :debugger.\nIEx.pry The name “pry” is an old friend in the Ruby ecosystem but it has a different behavior in Elixir.","title":"Debugging techniques in Elixir"},{"content":"To translate or not to translate? We have been asking ourselves the same question in one of our latest Phoenix projects. Even though internationalizing our application is planned a bit ahead in our roadmap, we have decided to do an initial evaluation of the translation tools in the Elixir ecosystem, and we were pleasantly surprised by what it has to offer.\n Important: This post was original published by me in http://blog.plataformatec.com.br/2016/03/using-gettext-to-internationalize-a-phoenix-application/ on March 15, 2016.\n The Phoenix framework ships with internationalization (i18n) and localization (l10n) system called Gettext since version 1.1. Gettext is a tool for writing multilingual programs used as a standard by many communities, meaning there is a great set of tooling for developers and translators.\nLet’s start! The idea behind Gettext is that it translates messages based on the string itself and not on “keys”. For example, instead of specifying translations as keys, as in translate “view.welcome”, we simply use the gettext “Hello there!” function for every string in the app.\nWe have noticed this approach comes with two large benefits:\n When using “view.welcome” strings, it always required two steps from developers. The first was to use “view.welcome” in our templates and then add the translated string to a configuration file. Using gettext is a single step as it will use the given string if no translation is available; We can translate our applications without losing context since we keep the original text. We maintained applications in the past that relied heavily on “custom.message” strings and the extra level of indirection was always hard to work with. Given those benefits, we have decided to tag already our strings with gettext calls, saving us from future work without a loss in productivity or maintainability.\nIn this post, we will show you how we did that and how to translate effectively your app when the time comes in the future by running two tasks. Before, let’s take a look at the Gettext structure when we start a new Phoenix project.\nStructure Gettext uses two kinds of files: *.po and *.pot. These files are stored in priv/gettext/. For now, we have only the file errors that are used by Ecto. The structure is:\npriv/gettext └─ en_US | └─ LC_MESSAGES | └─ errors.po └─ errors.pot POT file POT means Portable Object Template and these files are generated automatically by:\nmix gettext.extract A new Phoenix project already has a gettext call in the web/template/pages/index.html.eex with \u0026lt;h2\u0026gt;\u0026amp;lt;%= gettext “Welcome to %{name}”, name: “Phoenix!” %\u0026amp;gt;\u0026lt;/h2\u0026gt;.\nThe first time you run the task above, it will create a default.pot file with the text provided:\npriv/gettext └─ en_US | └─ LC_MESSAGES | └─ errors.po └─ default.pot └─ errors.pot The default.pot file is similar to:\n## This file is a PO Template file. `msgid`s here are often extracted from ## source code; add new translations manually only if they're dynamic ## translations that can't be statically extracted. Run `mix ## gettext.extract` to bring this file up to date. Leave `msgstr`s empty as ## changing them here as no effect; edit them in PO (`.po`) files instead. #: web/templates/page/index.html.eex:2 msgid \u0026quot;Welcome to %{name}\u0026quot; msgstr \u0026quot;\u0026quot; These files should not be modified manually because this will cause them to be used as a reference for your next files and languages. (well, kind of, as there is a special case that will be covered in another blog post).\nPO file PO means Portable Object and the files are based on the POT files. These are the files that you will use to add your translations. First, we need to generate them with the task:\nmix gettext.merge priv/gettext Now, we have a new PO file in our structure:\npriv/gettext └─ en_US | └─ LC_MESSAGES | └─ default.po | └─ errors.po └─ default.pot └─ errors.pot Let’s take a look at the new file:\n## `msgid`s in this file come from POT (.pot) files. Do not add, change, or ## remove `msgid`s manually here as they're tied to the ones in the ## corresponding POT file (with the same domain). Use `mix gettext.extract ## --merge` or `mix gettext.merge` to merge POT files into PO files. msgid \u0026quot;\u0026quot; msgstr \u0026quot;\u0026quot; \u0026quot;Language: en\\n\u0026quot; #: web/templates/page/index.html.eex:2 msgid \u0026quot;Welcome to %{name}\u0026quot; msgstr \u0026quot;\u0026quot; Gettext uses English by default. The msgid is the text provided in the gettext function andmsgstr is the translated value for it.\nWhy does my app work when I use Gettext without the translation files? By default, thegettext function will return the string passed in. With this approach, you can add gettextcalls whenever you start thinking about localizing.\nAdding new translations in our template Every time that we add a new call to gettext in the templates, we need to update our POT and PO files.\nmix gettext.extract mix gettext.merge priv/gettext After this, the new msgid will be available in your PO files. You could also run both tasks with a single one:\nmix gettext.extract --merge Adding new languages for our app Now I want to translate the app to pt_BR. The next step is running:\nmix gettext.merge priv/gettext --locale pt_BR This task will use the template files to generate the .PO files. Let’s see our structure after we ran the task:\npriv/gettext └─ en_US | └─ LC_MESSAGES | └─ errors.po | └─ default.po └─ pt_BR | └─ LC_MESSAGES | └─ errors.po | └─ default.po └─ default.pot └─ errors.pot What happens if I change my locale to pt_BR and I didn’t translate the msgid? The Gettext will fall back to the default language and your app will not crash.\nYou can do more with Gettext. Pluralize In addition to the simple translation, if you use gettext “Here is one string to translate”, you can pluralize. Example:\n# Plural translation number_of_apples = 4 ngettext \u0026quot;The apple is ripe\u0026quot;, \u0026quot;The apples are ripe\u0026quot;, number_of_apples Your PO file will be generated like:\nmsgid \u0026quot;The apple is ripe\u0026quot; msgid_plural \u0026quot;The apples are ripe\u0026quot; msgstr[0] \u0026quot;\u0026quot; msgstr[1] \u0026quot;\u0026quot; Interpolation Interpolation keys can be placed in msgids or msgid_plurals by enclosing them in %{ and }, like this: Example: gettext(\u0026quot;My name is %{name}\u0026quot;, name: @user.name). The PO file will be like:\nmsgid \u0026quot;My name is %{name}\u0026quot; msgstr \u0026quot;\u0026quot; Domains You can create domains to scope assess your translations. All your translations will be stored in the default domain. Ecto uses a custom domain called errors for validations. To use a custom domain, use: dgettext \u0026quot;errors\u0026quot;, \u0026quot;Here is an error message to translate\u0026quot;. The tasks will be responsible for creating the files for this domain.\nLocale per-process One more thing, Gettext stores the locale per-process (in the process dictionary) and per Gettext module. This means that you can use Gettext.put_locale/2 in a new process in order to change the locale for that process. You can change the default value in your config/config.exs with config :playfair, Playfair.Gettext, default_locale: \u0026quot;pt_BR\u0026quot;.\nEven after adding gettext functions, you probably need to work in some assets, currency, dates, and so on. But, the hard work, scanning all your files to add the translation, has already been done.\nYou can find more information in the Gettext documentation . Do you believe that the Gettext approach could have helped you?\n","permalink":"https://erichkist.com/using-gettext-to-internationalize-a-phoenix-application/","summary":"To translate or not to translate? We have been asking ourselves the same question in one of our latest Phoenix projects. Even though internationalizing our application is planned a bit ahead in our roadmap, we have decided to do an initial evaluation of the translation tools in the Elixir ecosystem, and we were pleasantly surprised by what it has to offer.\n Important: This post was original published by me in http://blog.","title":"Using Gettext to internationalize a Phoenix application"},{"content":"Writing tests is an important step in software development and everyone knows the benefits. In our last post, we took a look on how to write acceptance tests in Phoenix and today we will see how to configure CI to run the tests.\n Important: This post was original published by me in http://blog.plataformatec.com.br/2016/02/how-to-setup-ci-to-run-phoenix-projects/ on February 12, 2016.\n Install Erlang and Elixir We use Jenkins to run ours builds and Ansible to setup the agents. The following code are snippets from the tasks used for machine provisioning. Our agents are using Ubuntu, but you can check the Elixir Install section to follow the steps for another OS.\nStep 1: Add the Erlang Solutions repository: First, we need to add the Erlang Solution repo and its GPG key before updating the repo. With this step we can find the Erlang and Elixir packages.\n- name: Add Erlang Solutions repository apt_repository: \u0026gt; repo='deb https://packages.erlang-solutions.com/ubuntu/ {{ansible_distribution_release}} contrib' state=present update_cache=yes - name: Add the GPG key for Erlang Solutions apt_key: url: \u0026quot;https://packages.erlang-solutions.com/{{ ansible_distribution | lower }}/erlang_solutions.asc\u0026quot; state: present Step 2: Install Erlang and Elixir packages. We are using the latest version of Elixir but if you need to manage it you can take a look at a manager like kiex or asdf .\n- name: Install Erlang apt: pkg=esl-erlang state=latest - name: Install Elixir apt: pkg=elixir state=latest Step 3: Install Hex and Rebar. If you are new to Elixir/Erlang, you probably don’t know about these tools. Hex is the package manager for the Erlang ecosystem and you can learn more at https://hex.pm .\nRebar is an Erlang build tool, and it’s necessary to build the dependency poolboy. The taskmix local.rebar will install both rebar and rebar3. You can check the Mix.Tasks.Local.Rebar documentation to install one of them if you need.\n- name: Install Elixir Hex command: mix local.hex --force - name: Install Rebar command: mix local.rebar Running your tests We use Janky , along with Jenkins, which can execute a custom build configuration intoscript/cibuild that is stored at the root of the repository. Our Phoenix projects use the following script:\n#!/bin/bash -ex env source /etc/profile export POSTGRESQL_USER=\u0026#34;test\u0026#34; export POSTGRESQL_PASSWORD=\u0026#34;test\u0026#34; mix ecto.reset mix deps.get mix test Exporting ENV variables Our project is using Postgres and it isn’t a good practice to store the credentials in the version control. So, we export the credential to environment variables and get it in config/test.exs:\nconfig :my_app, MyApp.Repo, adapter: Ecto.Adapters.Postgres, username: System.get_env(\u0026#34;POSTGRESQL_USER\u0026#34;) || \u0026#34;postgres\u0026#34;, password: System.get_env(\u0026#34;POSTGRESQL_PASSWORD\u0026#34;) || \u0026#34;postgres\u0026#34;, database: \u0026#34;my_app_test\u0026#34;, hostname: \u0026#34;localhost\u0026#34;, pool: Ecto.Adapters.SQL.Sandbox, port: System.get_env(\u0026#34;POSTGRESQL_PORT\u0026#34;) || 5432 You can read more about this practice at Twelve-Factor App .\nReset your database Usually, each builder is responsible for provision in a new machine. Instead of this, we setup a machine that will run several builds from different projects while there is activity. Therefore, we need to reset the database to avoid side-effects with different schemas.\nThe task mix test will run the tasks ecto.create and ecto.migrate (you can check it intest/test_helper.exs). We could use mix ecto.destroy instead of mix ecto.reset, but we prefer to use the latter to be more explicit.\nInstall dependencies and run the tests Now, mix deps.get and mix test will install the project dependencies and run your tests.\nWhich tips do you have to install or use in CI to run Phoenix tests?\n","permalink":"https://erichkist.com/how-to-setup-ci-to-run-phoenix-projects/","summary":"Writing tests is an important step in software development and everyone knows the benefits. In our last post, we took a look on how to write acceptance tests in Phoenix and today we will see how to configure CI to run the tests.\n Important: This post was original published by me in http://blog.plataformatec.com.br/2016/02/how-to-setup-ci-to-run-phoenix-projects/ on February 12, 2016.\n Install Erlang and Elixir We use Jenkins to run ours builds and Ansible to setup the agents.","title":"How to Setup CI to Run Phoenix Projects"}]