<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title></title>
  <subtitle></subtitle>
  <id>https://www.endpointdev.com/blog/tags/jenkins/</id>
  <link href="https://www.endpointdev.com/blog/tags/jenkins/"/>
  <link href="https://www.endpointdev.com/blog/tags/jenkins/" rel="self"/>
  <updated>2020-05-25T00:00:00+00:00</updated>
  <author>
    <name>End Point Dev</name>
  </author>
  
    <entry>
      <title>Designing flexible CI pipelines with Jenkins and Docker</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2020/05/flexible-ci-pipelines-jenkins-docker/"/>
      <id>https://www.endpointdev.com/blog/2020/05/flexible-ci-pipelines-jenkins-docker/</id>
      <published>2020-05-25T00:00:00+00:00</published>
      <author>
        <name>Will Plaut</name>
      </author>
      <content type="html">
        &lt;p&gt;&lt;img src=&#34;/blog/2020/05/flexible-ci-pipelines-jenkins-docker/pipes.jpg&#34; alt=&#34;Pipes&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://unsplash.com/photos/9AxFJaNySB8&#34;&gt;Photo&lt;/a&gt; by &lt;a href=&#34;https://unsplash.com/@realaxer&#34;&gt;Tian Kuan&lt;/a&gt; on &lt;a href=&#34;https://unsplash.com/&#34;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When deciding on how to implement continuous integration (CI) for a new project, you are presented with lots of choices. Whatever you end up choosing, your CI needs to work for you and your team. Keeping the CI process and its mechanisms clear and concise helps everyone working on the project. The setup we are currently employing, and what I am going to showcase here, has proven to be flexible and powerful. Specifically, I’m going to highlight some of the things Jenkins and Docker do that are really helpful.&lt;/p&gt;
&lt;h3 id=&#34;jenkins&#34;&gt;Jenkins&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.jenkins.io/&#34;&gt;Jenkins&lt;/a&gt; provides us with all the CI functionality we need and it can be easily configured to connect to projects on GitHub and our internal GitLab. Jenkins has support for something it calls a multibranch pipeline. A Jenkins project follows a repo and builds any branch that has a &lt;code&gt;Jenkinsfile&lt;/code&gt;. A &lt;code&gt;Jenkinsfile&lt;/code&gt; configures an individual pipeline that Jenkins runs against a repo on a branch, tag or merge request (MR).&lt;/p&gt;
&lt;p&gt;To keep it even simpler, we condense the steps that a &lt;code&gt;Jenkinsfile&lt;/code&gt; runs into shell scripts that live in &lt;code&gt;/scripts/&lt;/code&gt; at the root of the source repo to do things like test or build or deploy, such as &lt;code&gt;/scripts/test.sh&lt;/code&gt;. If a team member wants to know how the tests are run, it is right in that file to reference.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Jenkinsfile&lt;/code&gt; can be written in a declarative syntax or in plain Groovy. We have landed on the scripted Groovy syntax for its more fine-grained control of Docker containers. Jenkins also provides several ways to inspect and debug the pipelines with things like “Replay” in its GUI and using &lt;code&gt;input(&#39;wait here&#39;)&lt;/code&gt; in a pipeline to debug a troublesome step. The &lt;code&gt;input()&lt;/code&gt; function is especially useful when paired with Docker. The function allows us to pause the job and go to the Jenkins server where we use &lt;code&gt;docker ps&lt;/code&gt; to find the running container’s name. Then we use &lt;code&gt;docker exec -it {container name} bash&lt;/code&gt; to debug inside of the container with all of the Jenkins environment variables loaded. This has proven to be a great way to figure out why something isn’t working in our test stages.&lt;/p&gt;
&lt;h3 id=&#34;docker&#34;&gt;Docker&lt;/h3&gt;
&lt;p&gt;We love using &lt;a href=&#34;https://www.docker.com/&#34;&gt;Docker&lt;/a&gt; for our development and deployment for a variety of reasons. First, creating a Dockerfile for a project is essentially an exercise in figuring out how a project is built with a minimum of dependencies. Once a Docker container is built, the running container provides a great place to run tests as it is a clean checkout with little to no extra cruft.&lt;/p&gt;
&lt;p&gt;Using our Jenkins pipeline, we can take builds triggered by tags and push an associated tagged Docker image up to our registry. With Docker’s layering, pushes are often the shortest stage of the Jenkins job. Deploying that tag is as simple as doing a &lt;code&gt;docker pull&lt;/code&gt; on the target system. For the application deployment, we create a basic &lt;code&gt;docker-compose.yml&lt;/code&gt; to start and serve the project from within the container, forwarding whatever ports we need on the local system.&lt;/p&gt;
&lt;h3 id=&#34;example-jenkinsfile&#34;&gt;Example Jenkinsfile&lt;/h3&gt;
&lt;p&gt;Let’s take a look at a basic scripted &lt;code&gt;Jenkinsfile&lt;/code&gt; (scripted in Groovy) that utilizes a &lt;code&gt;Dockerfile&lt;/code&gt; in the source repo to build, test, and deploy a project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;node() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  properties([gitLabConnection(&amp;#39;gitlab-connect&amp;#39;)])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  def vueImage
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  def dockerTagName
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  stage(&amp;#39;Checkout&amp;#39;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    checkout scm
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  stage(&amp;#39;Build&amp;#39;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    vueImage = docker.build(&amp;#34;endpoint/vue-test&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  vueImage.inside(&amp;#39;-u 0&amp;#39;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    stage(&amp;#39;Test&amp;#39;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      sh &amp;#39;./scripts/test.sh&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  stage(&amp;#39;Tag/Push&amp;#39;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    docker.withRegistry(&amp;#39;https://registry.hub.docker.com&amp;#39;, &amp;#39;ep_dockerhub_creds&amp;#39;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      if (env.TAG_NAME != null) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vueImage.push(&amp;#34;${env.TAG_NAME}&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      } else {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        vueImage.push(&amp;#34;${env.BRANCH_NAME}&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The script’s first stage, &lt;code&gt;Checkout&lt;/code&gt;, checks out the repo using our &lt;code&gt;gitlab-connect&lt;/code&gt; credentials that are stored on the Jenkins server. It then moves to the &lt;code&gt;Build&lt;/code&gt; stage where it builds the image using the &lt;code&gt;Dockerfile&lt;/code&gt; in our repo and names it after the org/repo it will use on DockerHub. Then, inside of the running container we enter the &lt;code&gt;Test&lt;/code&gt; stage where we run the repo script &lt;code&gt;./scripts/test.sh&lt;/code&gt;. After the &lt;code&gt;.inside&lt;/code&gt; code block is closed the running container is stopped and removed. Finally, we get to the &lt;code&gt;Tag/Push&lt;/code&gt; stage where we push our Docker image up to DockerHub using another set of stored credentials. We tag it with either the &lt;code&gt;TAG_NAME&lt;/code&gt; or the &lt;code&gt;BRANCH_NAME&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This &lt;code&gt;Jenkinsfile&lt;/code&gt; provides us with a solid base to expand on. During development as requirements change, it’s easy to modify and update the &lt;code&gt;Jenkinsfile&lt;/code&gt;. We have the ability to run steps inside and outside of the Docker. Combined with bash scripts that live in the repo, we can do almost anything. Most of the job mechanics can be tuned, down to the specific status updates GitLab receives during a run.&lt;/p&gt;
&lt;p&gt;Say we want to handle a push a bit differently if the branch is named &lt;code&gt;Master&lt;/code&gt; or we want to add another stage and break out the &lt;code&gt;Test&lt;/code&gt; stage into &lt;code&gt;Unit Tests&lt;/code&gt; and &lt;code&gt;E2E Tests&lt;/code&gt;. These things are easily changed in the &lt;code&gt;Jenkinsfile&lt;/code&gt; and then run on Jenkins when pushed. There’s no need to merge to see the pipeline change. Every branch/​tag/​MR has its own pipeline. Deploying the Docker you just built is easy; just use your &lt;code&gt;TAG_NAME&lt;/code&gt; or &lt;code&gt;BRANCH_NAME&lt;/code&gt; with &lt;code&gt;docker pull endpoint/vue-test:{}&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Although the above script is just an example script, the &lt;code&gt;Jenkinsfile&lt;/code&gt;s we use in production are not far off from this in functionality and the ideas remain the same.&lt;/p&gt;
&lt;p&gt;Jenkins is not the easiest to configure as some of the required functionality comes from plugins, and getting the correct combination of plugins can be a challenge. That being said, the functionality it provides paired with Docker is amazing and definitely worth considering when setting up CI for a new project.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>Testing Django Applications</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2015/12/testing-django-applications/"/>
      <id>https://www.endpointdev.com/blog/2015/12/testing-django-applications/</id>
      <published>2015-12-14T00:00:00+00:00</published>
      <author>
        <name>Zdeněk Maxa</name>
      </author>
      <content type="html">
        &lt;p&gt;This post summarizes some observations and guidelines originating from introducing the &lt;a href=&#34;http://pytest.org/latest/&#34;&gt;pytest&lt;/a&gt; unit testing framework into our CMS (Content Management System) component of the &lt;a href=&#34;https://www.visionport.com/&#34;&gt;Liquid Galaxy&lt;/a&gt;.
Our Django-based CMS allows users to define scenes, presentations and assets (StreetView, Earth tours, panos, etc) to be displayed on the
&lt;a href=&#34;https://www.youtube.com/watch?v=2VonXkA6YYg&#34;&gt;Liquid Galaxy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The purpose of this blog post is to capture my &lt;a href=&#34;https://www.djangoproject.com/&#34;&gt;Django&lt;/a&gt; and testing study points, summarize useful resource links as well as to itemize some guidelines for implementing tests for newcomers to the project. It also provides a comparison between Python’s standard &lt;a href=&#34;https://docs.python.org/2/library/unittest.html&#34;&gt;unittest library&lt;/a&gt; and the aforementioned pytest. Its focus is on Django database interaction.&lt;/p&gt;
&lt;h3 id=&#34;versions-of-software-packages-used&#34;&gt;Versions of software packages used&lt;/h3&gt;
&lt;p&gt;This post describes some of our experiences at End Point in designing and working on comprehensive QA/CI facilities for a new system which is closely related to the Liquid Galaxy.&lt;/p&gt;
&lt;p&gt;The experiments were done on Ubuntu Linux 14.04:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;python (2.7.6) and its corresponding version of unittest&lt;/li&gt;
&lt;li&gt;django 1.7 (current recent is 1.9 but our CMS uses still 1.7 version)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pytest-django.readthedocs.org/en/latest/&#34;&gt;pytest-django 2.8.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;pytest 2.7.2 (with py 1.4.30)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pypi.python.org/pypi/virtualenv&#34;&gt;virtualenv 13.1.2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://factoryboy.readthedocs.org/en/latest/&#34;&gt;factory_boy 2.6.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;testing-django-applications&#34;&gt;Testing Django Applications&lt;/h3&gt;
&lt;p&gt;We probably don’t need to talk much about the importance of testing. Writing tests along with the application code has become standard over the years. Surely, developers may fall into a trap of their own prejudice when creating testing conditions which would still result in faulty software but the likelihood of buggy software is certainly higher on a code that has no QA measures. If the code works and is untested, it means it works by accident, they say.&lt;/p&gt;
&lt;p&gt;As a rule of thumb, unit tests should be very brief testing items seldom interacting with any external services such as the database. Integration tests on the other hand often communicate with external components.&lt;/p&gt;
&lt;p&gt;This post will heavily reference an example minimal Django application written for the purpose of experimenting on
&lt;a href=&#34;https://github.com/zdenekmaxa/examples/tree/master/python/django-testing&#34;&gt;Django testing&lt;/a&gt;.
Its README file contains some set up and requirement notes. Also, I am not going to list (m)any code snippets here but rather reference the functional application and its test suite. Hence the points below qualify for more or less assorted little topics or observations.&lt;/p&gt;
&lt;p&gt;In order to benefit from this post, it will be helpful to follow the README and interact (run tests that is) with the demo django-testing application.&lt;/p&gt;
&lt;h3 id=&#34;basic-django-unittest-versus-pytest-basic-examples&#34;&gt;Basic Django unittest versus pytest basic examples&lt;/h3&gt;
&lt;p&gt;This pair of test modules shows the differences between Django TestCase (unittest) and pytest-django (pytest) frameworks.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/zdenekmaxa/examples/blob/master/python/django-testing/tests/test_unittest_style.py&#34;&gt;test_unittest_style.py&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The base Django TestCase class derives along this tree:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    django.test.TestCase
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        django.test.TransactionTestCase
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            django.test.SimpleTestCase
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                unittest.TestCase&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Django adds (among any other aspects) handling of database, the documentation is
&lt;a href=&#34;https://docs.djangoproject.com/en/1.7/topics/testing/overview/&#34;&gt;here&lt;/a&gt;, on top of the Python standard unittest library.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/zdenekmaxa/examples/blob/master/python/django-testing/tests/test_pytest_style.py&#34;&gt;test_pytest_style.py&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;this is a pytest style implementation of the same tests and pytest-django plug-in adds, among other features, Django database handling support.&lt;/p&gt;
&lt;p&gt;The advantage of unittest is that it comes with the Python installation—​it’s a standard library. That means that one does not have to install anything for writing tests, unlike pytest which is a third-party library and needs to be installed separately. While the absence of additional installation is certainly a plus, it’s dubious whether being a part of Python distribution is a benefit. I seem to recall Guido Van Rossum during Europython 2010 having said the the best thing for pytest is not being part of the Python standard set of libraries for its lively development and evolution would be slowed down by the inclusion.&lt;/p&gt;
&lt;p&gt;There are very good talks and articles summarizing advantages of pytest. For me personally, the reporting of error
context is supreme. No boiler-plate (no inheritance), using plain Python asserts instead of
many &lt;a href=&#34;https://docs.python.org/2/library/unittest.html#assert-methods&#34;&gt;assert* methods&lt;/a&gt; and
flexibility (function, class) are other big plus points&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://speakerdeck.com/pelme/testing-django-applications-with-py-dot-test-europython-2013&#34;&gt;Testing Django applications with py.test (EuroPython 2013)&lt;/a&gt; (very good)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://prezi.com/knnfwewm7lvw/pytest-rapid-multi-purpose-testing/&#34;&gt;pytest presentation from its author&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.pydanny.com/pytest-no-boilerplate-testing.html&#34;&gt;very brief pytest introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://mathieu.agopian.info/presentations/2015_06_djangocon_europe/&#34;&gt;switch to pytest&lt;/a&gt;, rich features descriptions, has some Django touches&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As the comment in the &lt;strong&gt;test_unittest_style.py&lt;/strong&gt; file says, this particular unittest-based test module can be run by both
Django &lt;strong&gt;manage.py&lt;/strong&gt; (which boils down to unittest lookup discovery on a lower layer) or by &lt;strong&gt;py.test&lt;/strong&gt; (pytest).&lt;/p&gt;
&lt;p&gt;It should also be noted, that pytest’s flexibility can &lt;a href=&#34;http://stackoverflow.com/questions/21430900/py-test-skips-test-class-if-constructor-is-defined&#34;&gt;bite back&lt;/a&gt; if something gets overlooked.&lt;/p&gt;
&lt;h3 id=&#34;django-database-interaction-unittest-versus-pytest-advanced-examples&#34;&gt;Django database interaction unittest versus pytest (advanced examples)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/zdenekmaxa/examples/blob/master/python/django-testing/tests/test_unittest_advanced.py&#34;&gt;test_unittest_advanced.py&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since this post concentrates on pytest and since it’s the choice for our LG CMS project
(naturally :-), this unittest example just shows how the
&lt;strong&gt;test (fresh) database&lt;/strong&gt; is determined and how Django migrations are run at each test suite execution. Just as described in
the &lt;a href=&#34;https://docs.djangoproject.com/en/1.7/topics/testing/overview/&#34;&gt;Django documentation&lt;/a&gt;: “If your tests rely on database access such as creating or querying models, be sure to create your test classes as subclasses of django.test.TestCase rather than unittest.TestCase.”&lt;/p&gt;
&lt;p&gt;That is true for database interaction but not completely true when using pytest. And “Using unittest.TestCase avoids the cost of running each test in a transaction and flushing the database, but if your tests interact with the database their behavior will vary based on the order that the test runner executes them. This can lead to unit tests that pass when run in isolation but fail when run in a suite.”
&lt;strong&gt;django.test.TestCase&lt;/strong&gt;, however, ensures that each test runs inside a transaction to provide isolation.
The transaction is rolled back once the test case is over.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/zdenekmaxa/examples/blob/master/python/django-testing/tests/test_pytest_advanced.py&#34;&gt;test_pytest_advanced.py&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This file represents the actual core of the test experiments for this blog / demo app and shows various pytest features and approaches typical for this framework as well as Django (pytest-django that is) specifics.&lt;/p&gt;
&lt;h3 id=&#34;django-pytest-notes-advanced-example&#34;&gt;Django pytest notes (advanced example)&lt;/h3&gt;
&lt;p&gt;Much like the unittest documentation, the &lt;a href=&#34;https://pytest-django.readthedocs.org/en/latest/&#34;&gt;pytest-django&lt;/a&gt; recommends avoiding database interaction in unittest and concentrate only on the logic which should be designed in such a fashion that it can be tested without database.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;test database name prefixed &lt;code&gt;test_&lt;/code&gt; (just like at the unittest example), the base value is taken from the database section of
the &lt;strong&gt;settings.py&lt;/strong&gt;. As a matter of fact, it’s possible to run the test suite after previously dropping the main database,
the test suite interacts only with &lt;code&gt;test_&lt;/code&gt; + DATABASE_NAME&lt;/li&gt;
&lt;li&gt;migration execution before any database interaction is carried out (similarly to unittest example)&lt;/li&gt;
&lt;li&gt;database interaction marked by a Python decorator &lt;strong&gt;@pytest.mark.django_db&lt;/strong&gt; on the method or class level (or stand-alone function level). It’s in fact the &lt;strong&gt;first&lt;/strong&gt; occurrence of this marker which triggers the database set up (its creation and migrations handling). Again analogously to unittest (django.test.TestCase), the test case is wrapped in a database transaction which puts the database back into the state prior to the test case. The database &lt;code&gt;test_&lt;/code&gt; + DATABASE_NAME itself is dropped once the test suite run is over. The database is not dropped if &lt;code&gt;--db-reuse&lt;/code&gt; option is used. The production DATABASE_NAME remains untouched during the test suite run (more about this below)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pytest_djangodb_only.py — setup_method&lt;/strong&gt; — run this module separately and the data created in setup_method end up &lt;strong&gt;NOT&lt;/strong&gt; in the &lt;code&gt;test_&lt;/code&gt; + DATABASE_NAME database but in the standard one (as configured in the &lt;strong&gt;settings.py&lt;/strong&gt; which would be the production database likely)! Also this data won’t be rolled back. When run separately, this test module will pass (but still the production database would be tainted). It may or may not fail on the second and subsequent run depending whether it creates any unique data. When run within the test suite, the database call from the setup_method will fail despite the presence of the class django_db marker. This has been very important to realize.
Recommendation: do not include database interaction in the pytest special methods
(such assetup_method or teardown_method, etc), &lt;strong&gt;only include database interaction in the test case methods&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The error message &lt;code&gt;Failed: Database access not allowed, use the &amp;quot;django_db&amp;quot; mark to enable&lt;/code&gt; was seen on a database error on a method which actually had the marker. This output is not to be 100% trusted&lt;/li&gt;
&lt;li&gt;data model &lt;strong&gt;factories&lt;/strong&gt; are discussed separately below&lt;/li&gt;
&lt;li&gt;lastly the test module shows Django Client instance and calling an HTTP resource&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;pytest-setup_method&#34;&gt;pytest setup_method&lt;/h3&gt;
&lt;p&gt;While the fundamental differences between unittest and pytest were discussed, there is something to be said about Django
specific differences of the two. There is different database-related behaviour of
&lt;strong&gt;unittest setUp method&lt;/strong&gt; versus the &lt;strong&gt;pytest setup_method method&lt;/strong&gt;. The setUp is included in the transaction and database interactions are rolled back once the test case is over. The setup_method is not included in the transaction. Moreover, interacting with the database from setup_method results in faulty behaviour and difference depending whether the test module is run on its own or as a part of the whole test suite.&lt;/p&gt;
&lt;p&gt;The bottom line is: do not include database interaction in setup_method. This setUp, setup_method behaviour was already shown in the basic examples. And more description and demonstration of this behaviour is in the file: &lt;strong&gt;pytest_djangodb_only.py&lt;/strong&gt;. This actually revealed the fact that using django_db database fixture is not supported in special pytest methods and the aforementioned error message is misleading (more references &lt;a href=&#34;https://github.com/pytest-dev/pytest-django/issues/297&#34;&gt;here&lt;/a&gt; and
&lt;a href=&#34;http://stackoverflow.com/questions/34089425/django-pytest-setup-method-database-issue&#34;&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;When running the whole test suite, this file won’t be collected (its name lacks &lt;code&gt;test_&lt;/code&gt; string).
It needs to be renamed to be included in the test suite run.&lt;/p&gt;
&lt;h3 id=&#34;json-data-fixtures-versus-factories-pytest-advanced-example&#34;&gt;JSON data fixtures versus factories (pytest advanced example)&lt;/h3&gt;
&lt;p&gt;The traditional way of interacting with some test data was to perform following steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;have data loaded in the database&lt;/li&gt;
&lt;li&gt;python manage.py dumpdata&lt;/li&gt;
&lt;li&gt;the produced JSON file is dragged along the application test code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;call_command(&amp;ldquo;loaddata&amp;rdquo;, fixture_json_file_name)&lt;/strong&gt; happens at each test suite run&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The load is expensive, the JSON dump file is hard to maintain manually if the original modified copy and the current needs diverge (the file has integer primary keys value, etc). Although even the recent Django testing documentation mentions usage of JSON data fixtures, the approach is considered discouraged and the goal is recommended to achieve by means of loading the data in migrations or using model data factories.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.caktusgroup.com/blog/2013/07/17/factory-boy-alternative-django-testing-fixtures/&#34;&gt;This talk&lt;/a&gt; for example compares the both approaches in favour of &lt;a href=&#34;https://factoryboy.readthedocs.org/en/latest/&#34;&gt;factory_boy library&lt;/a&gt;.
A quote from the article:
“Factory Boy is a Python port of a popular Ruby project called Factory Girl. It provides a declarative syntax for how new instances should be created. &amp;hellip; Using fixtures for complex data structures in your tests is fraught with peril. They are hard to maintain and they make your
tests slow. Creating model instances as they are needed is a cleaner way to write your tests which will make them faster and more maintainable.”&lt;/p&gt;
&lt;p&gt;The file &lt;strong&gt;test_pytest_advanced.py&lt;/strong&gt; demostrates interaction with factories defined in the module
&lt;strong&gt;factories.py&lt;/strong&gt;, the basic very easy-to-use features.&lt;/p&gt;
&lt;p&gt;Despite its ease of use, the factory_boy is a powerful library capable of modeling
&lt;a href=&#34;http://factoryboy.readthedocs.org/en/latest/recipes.html#many-to-many-relation-with-a-through&#34;&gt;Django’s ORM many-to-many relationships&lt;/a&gt;, among other features.&lt;/p&gt;
&lt;h3 id=&#34;additional-useful-links&#34;&gt;Additional useful links&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.djangoproject.com/en/1.7/topics/testing/overview/&#34;&gt;Django 1.7 testing&lt;/a&gt; — version used in the demo application&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.djangoproject.com/en/2.0/topics/testing/overview/&#34;&gt;Django 2.0 testing&lt;/a&gt; — latest stable version&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.effectivedjango.com/&#34;&gt;Effective Django&lt;/a&gt; — testing covered already in the second chapter of the book&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.effectivedjango.com/orm.html#factoryboy-example&#34;&gt;Effective Django factory_boy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://carljm.github.io/django-testing-slides&#34;&gt;Django testing&lt;/a&gt; — excellent PyCon talk, slides covering pytest, fixtures vs factories, etc&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;You should have a good idea about testing differences via unittest and pytest in the Django environment. The emphasis has been put on pytest (django-pytest) and some recommended approaches. The demo application django-testing brings functional test cases demonstrating the behaviour and features discussed. The articles and talks listed in this post were extremely helpful and instrumental in gaining expertise in the area and introducing rigorous testing approach into the production application.&lt;/p&gt;
&lt;p&gt;Any discrepancy between the behaviour described above and on your own setup may originate from different software versions. In any case, if anything is not clear enough, please let me know in the comments.&lt;/p&gt;

      </content>
    </entry>
  
    <entry>
      <title>The Portal project — Jenkins Continuous Integration summary</title>
      <link rel="alternate" href="https://www.endpointdev.com/blog/2015/06/the-portal-project-jenkins-continuous/"/>
      <id>https://www.endpointdev.com/blog/2015/06/the-portal-project-jenkins-continuous/</id>
      <published>2015-06-09T00:00:00+00:00</published>
      <author>
        <name>Zdeněk Maxa</name>
      </author>
      <content type="html">
        &lt;p&gt;This post describes some of our experiences at End Point in designing and working on comprehensive QA/CI facilities for a new system which is closely related to the &lt;a href=&#34;https://www.visionport.com/&#34;&gt;Liquid Galaxy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Due to the design of the system, the full deployment cycle can be &lt;a href=&#34;/blog/2015/02/testing-your-chef-repo-pull-requests/&#34;&gt;rather lengthy&lt;/a&gt; and presents us with extra reasons for investing heavily in unit test development. Because of the very active ongoing development on the system we benefit greatly from running the tests in an automated fashion on the &lt;a href=&#34;https://jenkins-ci.org/&#34;&gt;Jenkins CI&lt;/a&gt; (Continuous Integration) server.&lt;/p&gt;
&lt;h3 id=&#34;our-projects-ci-anatomy&#34;&gt;Our Project’s CI Anatomy&lt;/h3&gt;
&lt;p&gt;Our Jenkins CI service defines 10+ job types (a.k.a. Jenkins projects) that cover our system. These job types differ as far as source code branches are concerned, as well as by combinations of the types of target environments the project builds are executed on.&lt;/p&gt;
&lt;p&gt;The skeleton of a Jenkins project is what one finds under the &lt;strong&gt;Configure&lt;/strong&gt; section on the Jenkins service webpage. The source code repository and branch are defined here. Each of our Jenkins projects also fetches a few more source code repositories during the build pre-execution phase.&lt;/p&gt;
&lt;p&gt;The environment variables are defined in a flat text file:&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;
&lt;a href=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-0-big.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-0.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Another configuration file is in the JSON format and defines variables for the test suite itself.
Furthermore, we have a preparation phase bash script and then a second bash script which eventually executes the test suite.&lt;/p&gt;
&lt;p&gt;Factoring out all degrees of freedom into two pairs of externally managed (by &lt;a href=&#34;https://www.chef.io/&#34;&gt;Chef&lt;/a&gt;) concise files allows for pure and simple Jenkins job build definition:&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;
&lt;a href=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-1-big.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-1.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;It’s well possible to have all variables and content of the bash scripts laid out directly in the corresponding text fields in the Jenkins configuration. We used to have that. It’s actually a terrible practice and the above desire for purity comes from a tedious and clumsy experience that changing a variable (e.g. an URL or such) in 10+ job types involves an unbearable amount of mouse clicking through the Jenkins service webpage. Performing some level of debugging of the CI environment (like when setting up &lt;a href=&#34;http://wiki.ros.org/&#34;&gt;ROS stack&lt;/a&gt; which the project &lt;a href=&#34;/blog/2015/03/simple-cross-browser-communication-ros/&#34;&gt;depends on&lt;/a&gt;) one is in for repetitive strain injury.&lt;/p&gt;
&lt;p&gt;In essence, keeping knowledge about job types on the Jenkins server itself at a minimum and having it managed externally serves us well and is efficient. Another step forward would be managing everything (the entire job type definition) by Chef. We have yet to experiment with the already existing Chef community cookbooks for Jenkins.&lt;/p&gt;
&lt;p&gt;The tests themselves are implemented in &lt;a href=&#34;https://www.python.org/&#34;&gt;Python&lt;/a&gt; using &lt;a href=&#34;https://docs.pytest.org/en/latest/&#34;&gt;pytest&lt;/a&gt; unit testing envelope. The test cases depend on &lt;a href=&#34;http://www.seleniumhq.org/&#34;&gt;Selenium&lt;/a&gt;—​the web automation framework. Python drives the browser through Selenium according to testing scenarios, sometimes rather complex. The Selenium framework provides handles by which the browser is controlled—​this includes user data input, clicking buttons, etc.&lt;/p&gt;
&lt;p&gt;We use Selenium in two modes:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;local mode:&lt;/strong&gt;
selenium drives a browser running on the Jenkins CI machine itself, locally. The browser runs in the &lt;a href=&#34;https://www.x.org/releases/X11R7.6/doc/man/man1/Xvfb.1.xhtml&#34;&gt;Xvfb&lt;/a&gt; environment. In this case everything runs on the Jenkins master machine.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;remote mode:&lt;/strong&gt;
the remote driver connects to a browser running on a remote machine (node A, B) and drives the browser there, as described in the diagram below. The test cases are run on the Jenkins slave machine located on a private network. The only difference between browser A and B is that they load their different respective Chrome extensions.&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;
&lt;a href=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-2-big.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-2.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The usual unit testing assertions are made on the state or values of HTML elements in the web page.&lt;/p&gt;
&lt;h3 id=&#34;custom-dashboard&#34;&gt;Custom dashboard&lt;/h3&gt;
&lt;p&gt;Our Jenkins server runs builds of 10+ various job types. The builds of each type are executed periodically and the builds are also triggered by git pushes as well as by git pull requests. As a result, we get a significant number of builds on daily basis.&lt;/p&gt;
&lt;p&gt;While Jenkins CI is extensible with very many plugins available out there, enabling and configuring a plugin gets cumbersome as the number of job types to configure rises. This is just to explain my personal aversion to experimenting with plugins on Jenkins for our project.&lt;/p&gt;
&lt;p&gt;The Jenkins service webpage itself does not offer creating a simple aggregated view across a number of job types to allow for a simple, concise, single page view.
Natively, there is just the single job type trends &lt;strong&gt;$JOB_URL/buildTimeTrend&lt;/strong&gt; page (see below).&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;
&lt;a href=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-3-big.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-3.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;A view which immediately tells whether there is an infrastructure problem (such as loss of connectivity) or conveys straight away that everything passes on Jenkins,  seems to be missing. Such a view or feature is even more important in an environment suffering from occasional transient issues. Basically, we wanted a combination of &lt;a href=&#34;https://wiki.jenkins-ci.org/display/JENKINS/Dashboard+View&#34;&gt;JENKINS/Dashboard+View&lt;/a&gt; and &lt;a href=&#34;https://wiki.jenkins-ci.org/display/JENKINS/Project+Statistics+Plugin&#34;&gt;JENKINS/Project+Statistics+Plugin&lt;/a&gt;, yet a lot simpler (see below).&lt;/p&gt;
&lt;p&gt;So yes, we coded up our own wheel, circular just according to our liking and thus developed the &lt;strong&gt;jenkins-watcher&lt;/strong&gt; application.&lt;/p&gt;
&lt;h3 id=&#34;jenkins-watcher&#34;&gt;jenkins-watcher&lt;/h3&gt;
&lt;p&gt;The application is freely available from this &lt;a href=&#34;https://github.com/EndPointCorp/jenkins-watcher&#34;&gt;repository&lt;/a&gt;, deploys on the Google App Engine platform and so utilizes certain platform features like Datastore, Cron jobs, TaskQueue and Access Control. A single configuration file contains mainly Jenkins CI server access credentials and job type names we are interested in. The above repository merely provides a template of this (secret) config file. &lt;a href=&#34;https://angularjs.org/&#34;&gt;AngularJS&lt;/a&gt; is used on the frontend and a smashing &lt;a href=&#34;https://pypi.python.org/pypi/jenkinsapi&#34;&gt;Jenkins API Python library&lt;/a&gt; is used to communicate from Python to the Jenkins CI server through its REST API. See below the result view it provides, the screenshot is cropped to show only 5 job types and their builds within the last 24 hours:&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;
&lt;a href=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-4-big.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-4.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Colour coding in green (passed), red (failed) and grey (aborted) shows a build status and is in fact just standard Jenkins colour coding. Each table row corresponds to 1 build of the build ID, build timestamp (start of the build), build duration, number of test cases which passed (P), failed (F), were skipped (S), or suffered from errors (E). The last item in the row is a direct link to the build console output, very handy for immediate inspection. In my experience, this is enough for a Jenkins babysitter’s swift daily checks. This is nothing fancy: no cool stats, graphs or plots. It is just a brief, useful overview.&lt;/p&gt;
&lt;p&gt;The application also performs periodic checks and aborts builds which take too long (yes, a Jenkins plugin with this functionality exists as well).&lt;/p&gt;
&lt;p&gt;For example, at a glance it’s obvious that the following failed builds suffer from some kind of transient infrastructure problems: no tests were run, nothing failed, the builds were marked as failure since some command in either their prep or build scripts failed:&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;
&lt;a href=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-5-big.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-5.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Or let’s take a look at another situation proving how simple visualisation can sometimes be very useful and immediately hint-providing. We observed a test case, interestingly only on just one particular job type, which sometimes ended up with a “Connection refused” error between the Selenium driver and the web browser (in the remote mode):&lt;/p&gt;
&lt;div class=&#34;separator&#34; style=&#34;clear: both; text-align: center;&#34;&gt;
&lt;a href=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-6-big.png&#34; imageanchor=&#34;1&#34; style=&#34;margin-left: 1em; margin-right: 1em;&#34;&gt;&lt;img border=&#34;0&#34; src=&#34;/blog/2015/06/the-portal-project-jenkins-continuous/image-6.png&#34;/&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Only after seeing the failures visualized, the pattern struck us. We immediately got an idea that something is rotten in the state of Denmark shortly after midnight: from that point on, the previously mysterious issue boiled down to an erroneous cronjob command. The killall command was killing everything and not just what it was supposed to (bug filed &lt;a href=&#34;http://sourceforge.net/p/psmisc/bugs/62/&#34;&gt;here&lt;/a&gt;):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;killall &amp;ndash;older-than 2h -r chromedriver&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Once we fixed the cronjob with a more complex but functional solution, without the killall command this time, so that the builds had not the chromedriver blanket pulled from under them while running, the mysterious error disappeared.&lt;/p&gt;
&lt;h3 id=&#34;summary-conclusion&#34;&gt;Summary, conclusion&lt;/h3&gt;
&lt;p&gt;Jenkins CI proved in general very useful for our Portal project. Keeping its configuration minimal and handling it externally worked most efficient. The custom jenkins-watcher application provides useful, aggregated, dashboard-like view. It is very easily configurable and not in any way dependent on the base project—​take it for free, configure a bit and push as your own Google App Engine project. The visualisation can sometimes be a useful debugging tool.&lt;/p&gt;

      </content>
    </entry>
  
</feed>
