自动化测试jenkins

This article was peer reviewed by Christopher Thomas and Peter Nijssen. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

本文由Christopher Thomas和Peter Nijssen进行了同行评审。 感谢所有SitePoint的同行评审人员使SitePoint内容达到最佳状态!



As our applications become more complex – with Composer dependencies, Webpack build scripts, and per-environment variables – we inevitably reach a point where testing all of these different intricacies becomes slow and laborious, especially when you’re tearing down and rebuilding the entire environment for each test. Likewise, code style might deviate over time and creating a production ready deployment archive requires a specific set of steps to be followed.

随着我们的应用程序变得更加复杂(具有Composer依赖项,Webpack构建脚本和每个环境变量),我们不可避免地达到了测试所有这些不同复杂性变得缓慢而费力的地步,尤其是当您拆除并重建整个环境时对于每个测试。 同样,代码样式可能会随时间而变化,创建可用于生产环境的部署归档文件需要遵循一组特定的步骤。

Suppose that, to test your application, you need to perform the following steps:

假设要测试您的应用程序,您需要执行以下步骤:

  1. Run composer install to ensure the dependencies are installed

    运行composer install以确保已安装依赖项

  2. Run php -l against each PHP file in the codebase to check for syntax errors

    对代码库中的每个PHP文件运行php -l以检查语法错误

  3. Run PHPUnit for unit testing

    运行PHPUnit进行单元测试
  4. Run Codeception for functional testing

    运行Codeception进行功能测试
Jenkins logo

If any of these steps fail then the software should be considered unsuitable for deployment until the errors have been addressed. As your software becomes more complex and the number of tests increases over time it can take many minutes to run the full suite which slows down your developers which in turn slows down the release process.

如果这些步骤中的任何一个失败,则在解决错误之前,应将软件视为不适合部署。 随着您的软件变得越来越复杂,并且测试数量随着时间的推移而增加,运行完整套件可能需要花费几分钟,这会降低开发人员的速度,进而降低发布过程的速度。

To help overcome this you can introduce a build server into your development workflow. A build server runs a piece of software that enables you to run a series of steps over and over again in the background, and if one of the steps fails the build server can inform you of the issue. If you’ve contributed to an open source project you may have seen a build server such as TravisCI or CircleCI in action. For example, every pull request on the Laravel project is tested by TravisCI to ensure the change doesn’t break any tests, then StyleCI ensures the code change matches the project code style.

为了解决这个问题,您可以将构建服务器引入开发工作流程。 构建服务器运行一个软件,该软件使您可以在后台反复执行一系列步骤,如果其中一个步骤失败,构建服务器可以将问题通知您。 如果您为一个开源项目做出了贡献,那么您可能已经看到了运行中的TravisCI或CircleCI之类的构建服务器。 例如, Laravel项目上的每个拉取请求都由TravisCI测试,以确保更改不会破坏任何测试,然后StyleCI确保代码更改与项目代码样式匹配。

laravel-checks.png

Jenkins is a popular open-source build server that this year had its 2.0 release. One of the principal features of this new release is the inclusion of the (previously optional) pipelines plugin as a core feature.

Jenkins是一种流行的开源构建服务器,今年已经发布了2.0版本。 此新版本的主要功能之一是包含(以前是可选的)管道插件作为核心功能。

A pipeline is a set of completely customizable steps that can be run in order to test and build your code. Pipelines are written in the Groovy scripting language which has a very simple syntax that is easy to get comfortable with. For example, if you wanted to describe the test steps described before as a pipeline, it might look similar to this:

管道是一组可以完全自定义的步骤,可以运行这些步骤来测试和构建代码。 管道使用Groovy脚本语言编写,该语言具有非常简单的语法,很容易适应。 例如,如果您想将前面描述的测试步骤描述为管道,则它看起来可能类似于以下内容:

node {
    stage("composer_install") {
        sh 'composer install'
    }

    stage("php_lint") {
        sh 'find . -name "*.php" -print0 | xargs -0 -n1 php -l'
    }

    stage("phpunit") {
        sh 'vendor/bin/phpunit'
    }

    stage("codeception") {
        sh 'vendor/bin/codecept run'
    }
}

The node statement tells Jenkins to assign a single build node (Jenkins can run either in a single-server mode, or a multi-node setup). Inside the node block are multiple stages, each of which performs a specific action. Jenkins will run each of the stages in turn and if any of them should fail then the entire build will fail and Jenkins will stop executing.

node语句告诉Jenkins分配一个构建节点(Jenkins可以在单服务器模式下运行,也可以在多节点设置下运行)。 节点块内部有多个阶段,每个阶段执行一个特定的动作。 Jenkins将依次运行每个阶段,如果其中任何一个阶段失败,则整个构建都会失败,并且Jenkins将停止执行。

From this simple example you could easily add additional stages with other tests, tell Jenkins to send a Slack notification for successful or failed builds, push successfully tested code into a release branch or mark a pull request as good to merge.

从这个简单的示例中,您可以轻松地在其他测试中添加其他阶段,告诉Jenkins为成功或失败的构建发送Slack通知,将成功测试的代码推送到发布分支中,或将合并请求标记为可以合并。

安装詹金斯 (Installing Jenkins)

Jenkins is very easy to install and for this tutorial we’re going to use Laravel Homestead to give a consistent virtual environment so you can play with Jenkins locally.

Jenkins非常易于安装,在本教程中,我们将使用Laravel Homestead提供一致的虚拟环境,以便您可以在本地使用Jenkins。

The first step is to install Laravel Homestead – there is a useful guide here. You only need to get the virtual machine up and running, we don’t need to configure any sites in the homestead.yaml file.

第一步是安装Laravel Homestead –这里有一个有用的指南 。 您只需要启动并运行虚拟机,就不需要在homestead.yaml文件中配置任何站点。

With your Homestead virtual machine up and running, SSH into it with vagrant ssh.

在您的Homestead虚拟机启动并运行后,使用vagrant ssh SSH进入它。

Homestead ships with all the dependencies we need, namely Git, PHP and Composer so we just need to install Jenkins itself. Following the Jenkins Debian package guide we need to perform the following steps.

Homestead附带了我们需要的所有依赖项,即Git,PHP和Composer,因此我们只需要安装Jenkins即可。 遵循Jenkins Debian软件包指南,我们需要执行以下步骤。

Run wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -. This command adds the code-signing key to Aptitude so the Jenkins packages from this repository will be trusted.

运行wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add - wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add - 。 此命令将代码签名密钥添加到Aptitude,因此将信任来自此存储库的Jenkins软件包。

Next, the package sources list needs updating so Aptitude knows about the Jenkins package repository. Execute echo "deb https://pkg.jenkins.io/debian-stable binary/" | sudo tee -a /etc/apt/sources.list.

接下来,软件包源列表需要更新,因此Aptitude会了解Jenkins软件包存储库。 执行echo "deb https://pkg.jenkins.io/debian-stable binary/" | sudo tee -a /etc/apt/sources.list echo "deb https://pkg.jenkins.io/debian-stable binary/" | sudo tee -a /etc/apt/sources.list

Finally, we need Aptitude to update its cache of available packages, and then install Jenkins:

最后,我们需要Aptitude更新其可用软件包的缓存,然后安装Jenkins:

sudo apt-get update && sudo apt-get install jenkins

Installing Jenkins will take approximately five minutes as it has quite a number of dependencies that also need installing.

安装Jenkins大约需要五分钟,因为它还具有许多需要安装的依赖项。

Once Jenkins is installed, open http://192.168.10.10:8080 in your browser (or your virtual host configured URL like homestead.app) and you should see a page titled “Unlock Jenkins”.

安装Jenkins后,在浏览器中打开http://192.168.10.10:8080 (或虚拟主机配置的URL,如homestead.app ),您应该会看到一个标题为“ Unlock Jenkins”的页面。

unlock-jenkins.png

Inside the VM, run the following command – sudo cat /var/lib/jenkins/secrets/initialAdminPassword and a random string of numbers and letters will be printed to the console. Copy and paste that string into the text field in the browser and press “Continue”.

在VM内,运行以下命令– sudo cat /var/lib/jenkins/secrets/initialAdminPassword ,随机数字和字母字符串将被打印到控制台。 复制该字符串并将其粘贴到浏览器的文本字段中,然后按“继续” 。

customise-jenkins.png

You’ll be presented with two options – choose “Install suggested plugins” and wait a few minutes while the plugins are downloaded and installed.

系统将为您提供两个选项-选择“安装建议的插件”,并等待几分钟,以下载和安装插件。

create-admin-user.png

On the next screen, enter the details of an admin user and press “Save and Finish”.

在下一个屏幕上,输入管理员用户的详细信息,然后按“保存并完成” 。

jenkins-dashboard.png

Jenkins is now installed and configured!

Jenkins现在已安装和配置!

创建第一份工作 (Creating Your First Job)

With Jenkins set up, we’re going to create a new build job that will do the following:

设置Jenkins之后,我们将创建一个新的构建作业,该作业将执行以下操作:

  1. Check out the latest build of laravel/framework

    查看最新版本的laravel/framework

  2. Install Composer dependencies

    安装Composer依赖项
  3. Run PHPUnit

    运行PHPUnit

Click the “create new jobs” link on the dashboard (or the “new item” link – they both do the same thing).

单击仪表板上的“创建新作业”链接(或“新项目”链接-它们都做同样的事情)。

create-new-item.png

Enter the name laravel, select “Pipeline”, then press “OK”.

输入名称laravel ,选择“管道”,然后按“确定” 。

You’ll now see a configuration editor for the job. Scroll down to the Pipeline section and enter the following script:

现在,您将看到该作业的配置编辑器。 向下滚动到“管道”部分,然后输入以下脚本:

node {
    stage('preparation') {
        // Checkout the master branch of the Laravel framework repository
        git branch: 'master', url: 'https://github.com/laravel/framework.git'
    }
    stage("composer_install") {
        // Run `composer update` as a shell script
        sh 'composer install'
    }
    stage("phpunit") {
        // Run PHPUnit
        sh 'vendor/bin/phpunit'
    }
}

Press “Save”. You will be redirected to the job overview page and after a few seconds you’ll see the job starting. If it doesn’t, just click the “Build Now” link in the left hand menu.

按“保存”。 您将被重定向到作业概述页面,几秒钟后,您将看到作业开始。 如果没有,只需单击左侧菜单中的“立即构建”链接。

first-build.png

As each stage we defined in the pipeline script begins and finishes, the Stage View will update.

随着我们在管道脚本中定义的每个阶段开始和结束,阶段视图将更新。

If you click on a stage, an overlay will appear with the log output for that stage which is really useful for debugging. Alternatively, you can click on the job in the left hand menu and click “Console”.

如果您单击某个阶段,则将显示该阶段的日志输出的覆盖,这对于调试非常有用。 或者,您可以单击左侧菜单中的作业,然后单击“控制台” 。

All Jenkins jobs have their own workspace which is an area in which you can safely create any temporary files that you might need as part of your build area. The workspace location for this job can be found in /var/lib/jenkins/workspace/laravel. By default, Jenkins won’t clear out this workspace for each build. If you need to do that, you could add a stage to the beginning of the pipeline script like so:

所有Jenkins作业都有其自己的工作区,在该工作区中,您可以安全地创建在构建区域中可能需要的任何临时文件。 可以在/var/lib/jenkins/workspace/laravel找到此作业的工作空间位置。 默认情况下,Jenkins不会为每个构建清除此工作空间。 如果需要这样做,可以在管道脚本的开头添加一个阶段,如下所示:

stage('cleanup') {
    // Recursively delete all files and folders in the workspace
    // using the built-in pipeline command
    deleteDir()
}

詹金斯档案 (The Jenkinsfile)

For our first job, we edited the pipeline script in the job settings interface. However, it would be much more useful to keep this script alongside our code in version control.

对于第一个作业,我们在作业设置界面中编辑了管道脚本。 但是,将这个脚本与我们的代码一起保留在版本控制中会更加有用。

With Jenkins’ pipelines you can write your pipeline as a Jenkinsfile script in the root of your code’s repository, which will be discovered and run. It is similar in concept to a .travis.yml or .circleci.yml file that you may already be familiar with.

使用Jenkins的管道,您可以将管道作为Jenkinsfile脚本编写在代码存储库的根目录中,这将被发现并运行。 它在概念上类似于您可能已经熟悉的.travis.yml或.circleci.yml文件。

On the laravel/framework Github project page, click the “fork” button in the top right and then click on your profile on the popup.

在laravel / framework Github项目页面上 ,单击右上角的“ fork”按钮,然后在弹出窗口中单击您的个人资料。

Create a new branch called jenkinsfile, then create a new file (you can do this directly in Github, you don’t have to clone the repository if you don’t want to).

创建一个名为jenkinsfile的新分支,然后创建一个新文件(您可以直接在Github中执行此操作,如果不想,则不必克隆存储库)。

create-jenkinsfile.png

Enter the following script and commit the file:

输入以下脚本并提交文件:

node {
    stage("composer_install") {
        // Run `composer update` as a shell script
        sh 'composer install'
    }
    stage("phpunit") {
        // Run PHPUnit
        sh 'vendor/bin/phpunit'
    }
}

Now go back to Jenkins and click the “Configure” button in the left hand menu. Scroll down to the Pipeline section and update the “definition” drop down to Pipeline script from SCM.

现在返回Jenkins,然后单击左侧菜单中的“配置”按钮。 向下滚动到“管道”部分,然后将“定义”下拉列表Pipeline script from SCM更新到“ Pipeline script from SCM 。

pipeline-from-scm.png

Enter the details for your forked repository, then hit “Save”.

输入分叉存储库的详细信息,然后单击“保存” 。

second-build.png

On the job overview screen click “Build now” in the left hand menu. You should have a successful build.

在作业概述屏幕上,单击左侧菜单中的“立即构建” 。 您应该具有成功的构建。

多分支管道项目 (Multibranch Pipeline Projects)

Most software projects utilize multiple branches in a repository to define various stages of a project. For example:

大多数软件项目利用存储库中的多个分支来定义项目的各个阶段。 例如:

  • The master branch represents the current production release

    master分支代表当前的生产版本

  • The develop branch represents the current staging release

    develop分支代表当前的暂存版本

  • The feature/new-profile-page branch may represent a work in progress feature.

    feature/new-profile-page分支可以表示正在进行的功能部件。

For each branch, you might want to run a number of custom actions – for example, whenever there is a commit of the master or develop branch, you want a full barrage of unit and integration tests run, whereas on all other branches just unit tests are enough.

对于每个分支,您可能需要运行许多自定义操作–例如,每当提交master或develop分支时,您都需要运行单元测试和集成测试的完整弹幕,而在所有其他分支上,只需单元测试够了。

The Jenkinsfile is written in the Groovy programming language, meaning we’ve got a full scripting language to play with.

Jenkinsfile用Groovy编程语言编写,这意味着我们可以使用完整的脚本语言。

In this example, I’ve added an if statement to check the branch name; if it is master or develop, then Jenkins should run an integration_tests stage.

在这个例子中,我添加了一个if语句来检查分支名称。 如果是master或develop ,那么Jenkins应该运行一个integration_tests阶段。

Following that, there is a switch statement which, depending on the branch name, creates a different deployment archive and registers it with the code deployment service (in this example, I’m demonstrating how this would work with Amazon Web Service’s CodeDeploy service).

之后,有一个switch语句,根据分支名称,该语句创建一个不同的部署档案并将其注册到代码部署服务中(在此示例中,我演示了如何将其与Amazon Web Service的CodeDeploy服务一起使用)。

node {
    stage("composer_install") {
        // Run `composer update` as a shell script
        sh 'composer update'
    }
    stage("phpunit") {
        // Run PHPUnit
        sh 'vendor/bin/phpunit'
    }

    // If this is the master or develop branch being built then run
    // some additional integration tests
    if (["master", "develop"].contains(env.BRANCH_NAME)) {
        stage("integration_tests") {
            sh 'vendor/bin/behat'
        }
    }

    // Create new deployment assets
    switch (env.BRANCH_NAME) {
        case "master":
            stage("codedeploy") {
                sh "aws deploy push --application-name My_App_Production --s3-location s3://my-app-production/build-${env.BUILD_NUMBER}.zip"
            }
            break
        case "develop":
            stage("codedeploy") {
                sh "aws deploy push --application-name My_App_Staging --s3-location s3://my-app-staging/build-${env.BUILD_NUMBER}.zip"
            }
            break
        default:
            // No deployments for other branches
            break
    }
}

Multibranch pipeline jobs are just as easy to set up – when you create a project, select “Multibranch Pipeline” as the type:

多分支管道作业很容易设置–创建项目时,选择“多分支管道”作为类型:

multibranch-pipeline.png

Then, in the configuration screen, set the pipeline definition dropdown to Pipeline script from SCM and enter the repository details.

然后,在配置屏幕中,将管道定义下拉列表设置为Pipeline script from SCM然后输入存储库详细信息。

Whenever the “Branch Indexing” option is run (it replaces the “Build Now” menu item inside the job), Jenkins will recursively iterate over each branch in the repository, and for each branch that has a Jenkinsfile and has changed recently, a new build for that branch will be run.

每当运行“分支索引”选项(它替换作业中的“立即构建”菜单项)时,Jenkins就会递归地遍历存储库中的每个分支,对于具有Jenkinsfile且最近已更改的每个分支, Jenkinsfile有一个新的该分支的构建将运行。

进一步发展 (Taking Things Further)

Jenkins owes much of it’s popularity to the extensive ecosystem of plugins.

Jenkins的受欢迎程度很大程度上归功于广泛的插件生态系统。

From the Jenkins home screen, click “Manage Jenkins” in the left hand menu, then click “Plugin Manager”.

在Jenkins主屏幕上,单击左侧菜单中的“管理Jenkins”,然后单击“插件管理器”。

jenkins-plugins.png

There are dozens of plugins that you can install and configure, ranging from testing plugins to integrations with cloud services.

您可以安装和配置许多插件,范围从测试插件到与云服务的集成。

For example, if your team uses Slack, you can enable the Slack Notification Plugin. Configure it in the main Jenkins settings screen (“Manage Jenkins” -> “Configure System”), then you can send Slack messages as part of your pipeline script:

例如,如果您的团队使用Slack,则可以启用Slack Notification Plugin 。 在主Jenkins设置屏幕( “管理Jenkins” -> “配置系统” )中对其进行配置 ,然后可以将Slack消息作为管道脚本的一部分发送:

node {

    slackSend color: '#4CAF50', channel: '#devops', message: "Started ${env.JOB_NAME} (<${env.BUILD_URL}|build ${env.BUILD_NUMBER}>)"

    try {

        stage("composer_install") {
            // Run `composer update` as a shell script
            sh 'composer update'
        }
        stage("phpunit") {
            // Run PHPUnit
            sh 'vendor/bin/phpunit'
        }

        slackSend color: '#4CAF50', channel: '#devops', message: "Completed ${env.JOB_NAME} (<${env.BUILD_URL}|build ${env.BUILD_NUMBER}>) successfully"

    } catch (all) {
        slackSend color: '#f44336', channel: '#devops', message: "Failed ${env.JOB_NAME} (<${env.BUILD_URL}|build ${env.BUILD_NUMBER}>) - <${env.BUILD_URL}console|click here to see the console output>"
    }
}

Once you’ve got Jenkins up and running on a server, you can easily configure a job to automatically build (or branch indexing to run) whenever a commit is pushed to your repository.

一旦在服务器上启动并运行了Jenkins,就可以轻松地配置作业,以在每次将提交推送到存储库时自动构建(或运行分支索引)。

For Github projects, ensure the Github Plugin is installed and enabled, then inside your Github repository settings enable service integration with the “Jenkins (Github plugin)” service.

对于Github项目,请确保已安装并启用Github插件 ,然后在您的Github存储库设置中启用与“ Jenkins(Github插件)”服务的服务集成。

For Bitbucket, this is slightly more complicated and I’ve detailed the steps required on my blog.

对于Bitbucket,这稍微复杂一些,我已经在Blog上详细介绍了所需的步骤 。

You should also ensure your Jenkins server is properly secured – you can either create users manually in Jenkins, delegate authentication to Github or Bitbucket using OAuth, or hook Jenkins into your organization’s LDAP directory. Likewise, you should always run Jenkins over SSL so your access to Jenkins can’t be easily intercepted.

您还应该确保您的Jenkins服务器受到适当保护–您可以在Jenkins中手动创建用户,使用OAuth将身份验证委派给Github或Bitbucket,或将Jenkins挂接到组织的LDAP目录中。 同样,您应该始终通过SSL运行Jenkins,这样就不会轻易阻止您对Jenkins的访问。

Your Jenkins installation also comes with a “Snippets Generator” which lets you view all of the enabled pipeline functions (such as sh, slackSend, deleteDir() and scm that we ‘ve already used). You can find a link to it in the left hand menu on the job overview screen.

您的Jenkins安装程序还附带一个“代码段生成器”,您可以通过它查看所有已启用的管道功能(例如我们已经使用过的sh , slackSend , deleteDir()和scm )。 您可以在作业概述屏幕的左侧菜单中找到指向它的链接。

摘要 (Summary)

Jenkins is a very powerful tool which can help make your software more reliable and save you and your team a lot of time. Humans are really bad at performing repetitive tasks over and over again, however, computers excel at it.

Jenkins是一个非常强大的工具,可以帮助您提高软件的可靠性,并为您和您的团队节省大量时间。 人类真的很难一遍又一遍地执行重复性的任务,但是计算机擅长于此。

If your team is being slowed down by tests which take over five minutes to run, offload that testing to Jenkins.

如果您的团队因需要五分钟以上的运行而减慢了速度,请将该测试卸载到Jenkins。

If you want to automatically produce deployment archives when a new production or staging build has become available, Jenkins can do that.

如果要在新的生产或暂存版本可用时自动产生部署档案,Jenkins可以这样做。

If you want to keep an eye on code quality and catch regressions before your customers do then Jenkins is ready to help.

如果您想在客户之前关注代码质量并赶上回归,那么Jenkins随时可以提供帮助。

Please leave any questions or comments below, and tell us about your most creative Jenkins pipelines!

请在下面留下任何问题或评论,并向我们介绍您最具创造力的Jenkins渠道!

翻译自: https://www.sitepoint.com/re-introducing-jenkins-automated-testing-with-pipelines/

自动化测试jenkins

更多推荐