python持续集成_与Python的持续集成:简介

python持续集成

When writing code on your own, the only priority is making it work. However, working in a team of professional software developers brings a plethora of challenges. One of those challenges is coordinating many people working on the same code.

自己编写代码时,唯一的优先事项就是使其正常工作。 但是,在专业软件开发人员团队中工作会带来很多挑战。 这些挑战之一是协调许多使用相同代码的人员。

How do professional teams make dozens of changes per day while making sure everyone is coordinated and nothing is broken? Enter continuous integration!

专业团队如何每天进行数十次更改,同时确保每个人都协调一致且没有任何问题? 输入持续集成!

In this tutorial you’ll:

在本教程中,您将:

  • Learn the core concepts behind continuous integration
  • Understand the benefits of continuous integration
  • Set up a basic continuous integration system
  • Create a simple Python example and connect it to the continuous integration system
  • 了解持续集成背后的核心概念
  • 了解持续集成的好处
  • 建立基本的持续集成系统
  • 创建一个简单的Python示例并将其连接到持续集成系统

Free Bonus: 5 Thoughts On Python Mastery, a free course for Python developers that shows you the roadmap and the mindset you’ll need to take your Python skills to the next level.

免费奖金: 关于Python精通的5个想法 ,这是针对Python开发人员的免费课程,向您展示了将Python技能提升到新水平所需的路线图和心态。

什么是持续集成? (What Is Continuous Integration?)

Continuous integration (CI) is the practice of frequently building and testing each change done to your code automatically and as early as possible. Prolific developer and author Martin Fowler defines CI as follows:

持续集成(CI)是一种频繁地自动并尽早构建和测试对代码所做的每次更改的实践。 多产的开发人员和作家Martin Fowler对CI的定义如下:

“Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily – leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible.” (Source)

“持续集成是一种软件开发实践,团队成员经常集成他们的工作,通常每个人至少每天集成一次-导致每天多次集成。 每个集成都通过自动构建(包括测试)进行验证,以尽快检测到集成错误。” ( 来源

Let’s unpack this.

让我们打开包装。

Programming is iterative. The source code lives in a repository that is shared by all members of the team. If you want to work on that product, you must obtain a copy. You will make changes, test them, and integrate them back into the main repo. Rinse and repeat.

编程是迭代的。 源代码位于由团队所有成员共享的存储库中。 如果要使用该产品,则必须获得一份副本。 您将进行更改,对其进行测试,然后将其重新集成到主存储库中。 冲洗并重复。

Not so long ago, these integrations were big and weeks (or months) apart, causing headaches, wasting time, and losing money. Armed with experience, developers started making minor changes and integrating them more frequently. This reduces the chances of introducing conflicts that you need to resolve later.

不久之前,这些集成相隔数周(数月)之久,造成了头痛,浪费时间和亏损。 有了经验,开发人员开始进行较小的更改并更频繁地进行集成。 这减少了引入需要稍后解决的冲突的机会。

After every integration, you need to build the source code. Building means transforming your high-level code into a format your computer knows how to run. Finally, the result is systematically tested to ensure your changes did not introduce errors.

每次集成之后,您都需要构建源代码。 构建意味着将高级代码转换为计算机知道如何运行的格式。 最后,系统地测试结果,以确保您的更改不会引入错误。

我为什么要在乎? (Why Should I Care?)

On a personal level, continuous integration is really about how you and your colleagues spend your time.

在个人层面上,持续集成实际上就是您和您的同事如何度过的时间。

Using CI, you’ll spend less time:

使用CI,您将花费更少的时间:

  • Worrying about introducing a bug every time you make changes
  • Fixing the mess someone else made so you can integrate your code
  • Making sure the code works on every machine, operating system, and browser
  • 每次更改时都担心引入错误
  • 修复其他人造成的混乱,以便您可以集成代码
  • 确保代码在每台机器,操作系统和浏览器上均有效

Conversely, you’ll spend more time:

相反,您将花费更多时间:

  • Solving interesting problems
  • Writing awesome code with your team
  • Co-creating amazing products that provide value to users
  • 解决有趣的问题
  • 与您的团队一起编写出色的代码
  • 共同创造为用户提供价值的惊人产品

How does that sound?

听起来怎么样?

On a team level, it allows for a better engineering culture, where you deliver value early and often. Collaboration is encouraged, and bugs are caught much sooner. Continuous integration will:

从团队的角度来看,它允许更好的工程文化,您可以在其中早日,经常地交付价值。 鼓励协作,并且可以更快地发现错误。 持续集成将:

  • Make you and your team faster
  • Give you confidence that you’re building stable software with fewer bugs
  • Ensure that your product works on other machines, not just your laptop
  • Eliminate a lot of tedious overhead and let you focus on what matters
  • Reduce the time spent resolving conflicts (when different people modify the same code)
  • 使您和您的团队更快
  • 让您充满信心,以更少的错误构建稳定的软件
  • 确保您的产品可以在其他计算机上运行,​​而不仅仅是笔记本电脑上
  • 消除许多繁琐的开销,让您专注于重要的事情
  • 减少解决冲突所花费的时间(当不同的人修改相同的代码时)

核心概念 (Core Concepts)

There are several key ideas and practices that you need to understand to work effectively with continuous integration. Also, there might be some words and phrases you aren’t familiar with but are used often when you’re talking about CI. This chapter will introduce you to these concepts and the jargon that comes with them.

您需要了解一些关键思想和实践,才能通过持续集成有效地工作。 另外,可能有一些您不熟悉的单词和短语,但是在谈论CI时经常使用。 本章将向您介绍这些概念及其附带的术语。

单一来源存储库 (Single Source Repository)

If you are collaborating with others on a single code base, it’s typical to have a shared repository of source code. Every developer working on the project creates a local copy and makes changes. Once they are satisfied with the changes, they merge them back into the central repository.

如果您要在单个代码库上与其他人进行协作,通常会拥有一个共享的源代码存储库。 每个从事该项目的开发人员都会创建一个本地副本并进行更改。 一旦他们对更改感到满意,便将其合并回中央存储库。

It has become a standard to use version control systems (VCS) like Git to handle this workflow for you. Teams typically use an external service to host their source code and handle all the moving parts. The most popular are GitHub, BitBucket, and GitLab.

使用像Git这样的版本控制系统(VCS)为您处理此工作流已成为一种标准。 团队通常使用外部服务来托管其源代码并处理所有活动部分。 最受欢迎的是GitHub,BitBucket和GitLab。

Git allows you to create multiple branches of a repository. Each branch is an independent copy of the source code and can be modified without affecting other branches. This is an essential feature, and most teams have a mainline branch (often called a master branch) that represents the current state of the project.

Git允许您创建存储库的多个分支 。 每个分支都是源代码的独立副本,可以在不影响其他分支的情况下进行修改。 这是一项重要功能,大多数团队都有代表项目当前状态的主线分支(通常称为主分支)。

If you want to add or modify code, you should create a copy of the main branch and work in your new, development branch. Once you are done, merge those changes back into the master branch.

如果要添加或修改代码,则应创建main分支的副本并在新的development分支中工作。 完成后,将这些更改合并回master分支。

Git Branching
Git branching
Git分支

Version control holds more than just code. Documentation and test scripts are usually stored along with the source code. Some programs look for external files used to configure their parameters and initial settings. Other applications need a database schema. All these files should go into your repository.

版本控制不仅仅包含代码。 文档和测试脚本通常与源代码一起存储。 一些程序会寻找用于配置其参数和初始设置的外部文件。 其他应用程序需要数据库架构。 所有这些文件都应放入您的存储库中。

If you have never used Git or need a refresher, check out our Introduction to Git and GitHub for Python Developers.

如果您从未使用过Git或需要复习,请查看我们的Python开发人员Git和GitHub简介

自动化构建 (Automating the Build)

As previously mentioned, building your code means taking the raw source code, and everything necessary for its execution, and translating it into a format that computers can run directly. Python is an interpreted language, so its “build” mainly revolves around test execution rather than compilation.

如前所述,构建代码意味着获取原始源代码以及执行它所需的一切,并将其转换为计算机可以直接运行的格式。 Python是一种解释型语言 ,因此它的“构建”主要围绕测试执行而不是编译。

Running those steps manually after every small change is tedious and takes valuable time and attention from the actual problem-solving you’re trying to do. A big part of continuous integration is automating that process and moving it out of sight (and out of mind).

每次进行细微更改后,手动执行这些步骤都是很繁琐的工作,并且需要花费宝贵的时间和精力来解决您要解决的实际问题。 持续集成的很大一部分是使该过程自动化并将其移到视线之外(和头脑之外)。

What does that mean for Python? Think about a more complicated piece of code you have written. If you used a library, package, or framework that doesn’t come with the Python standard library (think anything you needed to install with pip or conda), Python needs to know about that, so the program knows where to look when it finds commands that it doesn’t recognize.

这对Python意味着什么? 考虑一下您编写的更复杂的代码。 如果您使用的是Python标准库所没有的库,包或框架(请考虑使用pipconda安装所需的任何东西),则Python需要知道这一点,因此程序在找到时会知道在哪里寻找无法识别的命令。

You store a list of those packages in requirements.txt or a Pipfile. These are the dependencies of your code and are necessary for a successful build.

您可以将这些软件包的列表存储在requirements.txt或Pipfile中。 这些是您代码的依赖项,对于成功构建是必需的。

You will often hear the phrase “breaking the build.” When you break the build, it means you introduced a change that rendered the final product unusable. Don’t worry. It happens to everyone, even battle-hardened senior developers. You want to avoid this primarily because it will block everyone else from working.

您经常会听到“破坏体系”的说法。 当您中断构建时,意味着您进行了更改,使最终产品无法使用。 不用担心 它发生在每个人身上,甚至是经过艰苦奋战的高级开发人员。 您主要想避免这种情况,因为它会阻止其他所有人工作。

The whole point of CI is to have everyone working on a known stable base. If they clone a repository that is breaking the build, they will work with a broken version of the code and won’t be able to introduce or test their changes. When you break the build, the top priority is fixing it so everyone can resume work.

CI的全部目的是让每个人都在一个已知的稳定基础上工作。 如果他们克隆了破坏构建的存储库,那么他们将使用代码的损坏版本,并且将无法引入或测试其更改。 当您中断构建时,最重要的是修复它,以便每个人都可以恢复工作。

Pushing Breaking Changes to Master
Introducing a breaking change to the master branch
向主分支引入重大更改

When the build is automated, you are encouraged to commit frequently, usually multiple times per day. It allows people to quickly find out about changes and notice if there’s a conflict between two developers. If there are numerous small changes instead of a few massive updates, it’s much easier to locate where the error originated. It will also encourage you to break your work down into smaller chunks, which is easier to track and test.

如果构建是自动化的,则建议您频繁进行提交,通常每天进行多次。 它使人们可以快速找到有关更改的信息,并注意两个开发人员之间是否存在冲突。 如果有许多小的更改而不是一些大的更新,则更容易找到错误的来源。 它还会鼓励您将工作分解为较小的块,这更易于跟踪和测试。

自动化测试 (Automated Testing)

Since everyone is committing changes multiple times per day, it’s important to know that your change didn’t break anything else in the code or introduce bugs. In many companies, testing is now a responsibility of every developer. If you write code, you should write tests. At a bare minimum, you should cover every new function with a unit test.

由于每个人每天都要提交多次更改,因此一定要知道您的更改不会破坏代码中的其他内容或引入错误,这一点很重要。 在许多公司中,测试是每个开发人员的责任。 如果您编写代码,则应该编写测试。 至少,您应该使用单元测试来涵盖所有新功能。

Running tests automatically, with every change committed, is a great way to catch bugs. A failing test automatically causes the build to fail. It will draw your attention to the problems revealed by testing, and the failed build will make you fix the bug you introduced. Tests don’t guarantee that your code is free of bugs, but it does guard against a lot of careless changes.

进行所有更改后,自动运行测试是捕获bug的好方法。 测试失败会自动导致构建失败。 它将引起您对测试所揭示问题的关注,而失败的构建将使您修复所引入的错误。 测试不能保证您的代码没有错误,但是可以防止许多粗心的更改。

Automating test execution gives you some peace of mind because you know the server will test your code every time you commit, even if you forgot to do it locally.

自动执行测试可以让您高枕无忧,因为您知道每次提交时服务器都会测试您的代码,即使您忘记在本地进行也是如此。

使用外部持续集成服务 (Using an External Continuous Integration Service)

If something works on your computer, will it work on every computer? Probably not. It’s a cliché excuse and a sort of inside joke among developers to say, “Well, it worked on my machine!” Making the code work locally is not the end of your responsibility.

如果您的计算机可以正常工作,那么每台计算机都可以工作吗? 可能不是。 这是陈词滥调的借口,并且是开发人员中的一种玩笑,说:“好,它可以在我的机器上工作!” 使代码在本地运行并不是您的责任的终点。

To tackle this problem, most companies use an external service to handle integration, much like using GitHub for hosting your source code repository. External services have servers where they build code and run tests. They act as monitors for your repository and stop anyone from merging to the master branch if their changes break the build.

为了解决这个问题,大多数公司使用外部服务来处理集成,就像使用GitHub托管您的源代码存储库一样。 外部服务的服务器在其中构建代码并运行测试。 它们充当您存储库的监视器,并且如果他们的更改破坏了构建,则阻止任何人合并到master分支。

Automated Testing
Merging changes triggers the CI server
合并更改会触发CI服务器

There are many such services out there, with various features and pricing. Most have a free tier so that you can experiment with one of your repositories. You will use a service called CircleCI in an example later in the tutorial.

有很多这样的服务,具有各种功能和价格。 大多数都具有免费套餐,因此您可以尝试使用其中的一个存储库。 在本教程后面的示例中,将使用名为CircleCI的服务。

在暂存环境中进行测试 (Testing in a Staging Environment)

A production environment is where your software will ultimately run. Even after successfully building and testing your application, you can’t be sure that your code will work on the target computer. That’s why teams deploy the final product in an environment that mimics the production environment. Once you are sure everything works, the application is deployed in the production environment.

生产环境是您的软件最终运行的地方。 即使成功构建和测试了您的应用程序,您也无法确定您的代码将在目标计算机上运行。 这就是为什么团队在模仿生产环境的环境中部署最终产品的原因。 一旦确定一切正常,就将应用程序部署在生产环境中。

Note: This step is more relevant to application code than library code. Any Python libraries you write still need to be tested on a build server, to ensure they work in environments different from your local computer.

注意:此步骤与应用程序代码比库代码更相关。 您编写的所有Python库仍需要在构建服务器上进行测试,以确保它们在与本地计算机不同的环境中工作。

You will hear people talking about this clone of the production environment using terms like development environment, staging environment, or testing environment. It’s common to use abbreviations like DEV for the development environment and PROD for the production environment.

您会听到人们使用开发环境,登台环境或测试环境等术语谈论生产环境的这种克隆 。 通常在开发环境中使用DEV这样的缩写,在生产环境中使用PROD这样的缩写。

The development environment should replicate production conditions as closely as possible. This setup is often called DEV/PROD parity. Keep the environment on your local computer as similar as possible to the DEV and PROD environments to minimize anomalies when deploying applications.

开发环境应尽可能复制生产条件。 此设置通常称为DEV / PROD奇偶校验 。 保持本地计算机上的环境与DEV和PROD环境尽可能相似,以最大程度地减少部署应用程序时的异常情况。

DEV/PROD Parity
Test in a clone of the production environment
在生产环境的克隆中进行测试

We mention this to introduce you to the vocabulary, but continuously deploying software to DEV and PROD is a whole other topic. The process is called, unsurprisingly, continuous deployment (CD). You can find more resources about it in the Next Steps section of this article.

我们提到这一点是为了向您介绍词汇表,但是将软件持续部署到DEV和PROD则是另一个主题。 毫不奇怪,该过程称为连续部署(CD)。 您可以在本文的“ 下一步”部分中找到有关它的更多资源。

轮到你! (Your Turn!)

The best way to learn is by doing. You now understand all the essential practices of continuous integration, so it’s time to get your hands dirty and create the whole chain of steps necessary to use CI. This chain is often called a CI pipeline.

最好的学习方法就是做事。 现在,您已经了解了持续集成的所有基本实践,因此现在该动手掌握并创建使用CI所需的整个步骤链了。 该链通常称为CI 管道

This is a hands-on tutorial, so fire up your editor and get ready to work through these steps as you read!

这是一个动手教程,因此请启动编辑器,并准备在阅读时完成这些步骤!

We assume that you know the basics of Python and Git. We will use Github as our hosting service and CircleCI as our external continuous integration service. If you don’t have accounts with these services, go ahead and register. Both of these have free tiers!

我们假设您了解Python和Git的基础知识。 我们将使用Github作为我们的托管服务,并使用CircleCI作为我们的外部持续集成服务。 如果您没有这些服务的帐户,请继续注册。 两者都有免费套餐!

问题定义 (Problem Definition)

Remember, your focus here is adding a new tool to your utility belt, continuous integration. For this example, the Python code itself will be straightforward. You want to spend the bulk of your time internalizing the steps of building a pipeline, instead of writing complicated code.

记住,这里的重点是为工作带添加新工具,实现持续集成。 对于此示例,Python代码本身将非常简单。 您希望花费大量时间来内部化构建管道的步骤,而不是编写复杂的代码。

Imagine your team is working on a simple calculator app. Your task is to write a library of basic mathematical functions: addition, subtraction, multiplication, and division. You don’t care about the actual application, because that’s what your peers will be developing, using functions from your library.

想象您的团队正在开发一个简单的计算器应用程序。 您的任务是编写一个基本的数学函数库:加,减,乘和除。 您无需关心实际的应用程序,因为这是您的同龄人将使用库中的函数进行开发的内容。

创建一个仓库 (Create a Repo)

Log in to your GitHub account, create a new repository and call it CalculatorLibrary. Add a README and .gitignore, then clone the repository to your local machine. If you need more help with this process, have a look at GitHub’s walkthrough on creating a new repository.

登录到您的GitHub帐户,创建一个新的存储库,并将其命名为CalculatorLibrary。 添加自述文件和.gitignore,然后将存储库克隆到本地计算机。 如果您需要有关此过程的更多帮助,请查看GitHub创建新存储库的演练

建立工作环境 (Set up a Working Environment)

For others (and the CI server) to replicate your working conditions, you need to set up an environment. Create a virtual environment somewhere outside your repo and activate it:

为了让其他人(和CI服务器)复制您的工作条件,您需要设置一个环境。 在回购之外的某个地方创建一个虚拟环境并激活它:

 $ $ # Create virtual environment
# Create virtual environment
$ python3 -m venv calculator

$ python3 -m venv calculator

$ $ # Activate virtual environment (Mac and Linux)
# Activate virtual environment (Mac and Linux)
$ . calculator/bin/activate
$ . calculator/bin/activate

The previous commands work on macOS and Linux. If you are a Windows user, check the Platforms table in the official documentation. This will create a directory that contains a Python installation and tell the interpreter to use it. Now we can install packages knowing that it will not influence your system’s default Python installation.

先前的命令可在macOS和Linux上运行。 如果您是Windows用户,请查看官方文档中的Platforms表。 这将创建一个包含Python安装的目录,并告诉解释器使用它。 现在,我们可以安装软件包,知道它不会影响系统的默认Python安装。

编写一个简单的Python示例 (Write a Simple Python Example)

Create a new file called calculator.py in the top-level directory of your repository, and copy the following code:

创建一个名为新文件calculator.py在你的仓库的顶级目录,并复制下面的代码:

This is a bare-bones example containing two of the four functions we will be writing. Once we have our CI pipeline up and running, you will add the remaining two functions.

这是一个简单的示例,其中包含我们将要编写的四个函数中的两个。 一旦我们的CI管道启动并运行,您将添加其余两个功能。

Go ahead and commit those changes:

继续并进行以下更改:

 $ $ # Make sure you are in the correct directory
# Make sure you are in the correct directory
$ $ cd CalculatorLibrary
cd CalculatorLibrary
$ git add calculator.py
$ git add calculator.py
$ git commit -m $ git commit -m "Add functions for addition and subtraction"
"Add functions for addition and subtraction"

Your CalculatorLibrary folder should have the following files right now:

您的CalculatorLibrary文件夹现在应该具有以下文件:

Great, you have completed one part of the required functionality. The next step is adding tests to make sure your code works the way it’s supposed to.

太好了,您已经完成了所需功能的一部分。 下一步是添加测试,以确保您的代码按预期的方式工作。

编写单元测试 (Write Unit Tests)

You will test your code in two steps.

您将分两步测试代码。

The first step involves linting—running a program, called a linter, to analyze code for potential errors. flake8 is commonly used to check if your code conforms to the standard Python coding style. Linting makes sure your code is easy to read for the rest of the Python community.

第一步涉及整理-运行一个名为linter的程序,以分析代码中潜在的错误。 flake8通常用于检查您的代码是否符合标准的Python编码样式。 Linting可以确保您的代码在Python社区的其余部分都易于阅读。

The second step is unit testing. A unit test is designed to check a single function, or unit, of code. Python comes with a standard unit testing library, but other libraries exist and are very popular. This example uses pytest.

第二步是单元测试。 单元测试旨在检查单个功能或代码单元。 Python带有标准的单元测试库,但是其他库也存在并且非常流行。 本示例使用pytest

A standard practice that goes hand in hand with testing is calculating code coverage. Code coverage is the percentage of source code that is “covered” by your tests. pytest has an extension, pytest-cov, that helps you understand your code coverage.

与测试齐头并进的标准做法是计算代码覆盖率。 代码覆盖率是测试“覆盖”的源代码的百分比。 pytest具有扩展名pytest-cov ,可以帮助您了解代码覆盖率。

These are external dependencies, and you need to install them:

这些是外部依赖项,您需要安装它们:

 $ pip install flake8 pytest pytest-cov
$ pip install flake8 pytest pytest-cov

These are the only external packages you will use. Make sure to store those dependencies in a requirements.txt file so others can replicate your environment:

这些是您将使用的唯一外部软件包。 确保将这些依赖项存储在requirements.txt文件中,以便其他人可以复制您的环境:

To run your linter, execute the following:

要运行lint,请执行以下操作:

 $ flake8 --statistics
$ flake8 --statistics
./calculator.py:3:1: E302 expected 2 blank lines, found 1
./calculator.py:3:1: E302 expected 2 blank lines, found 1
./calculator.py:6:1: E302 expected 2 blank lines, found 1
./calculator.py:6:1: E302 expected 2 blank lines, found 1
2     E302 expected 2 blank lines, found 1
2     E302 expected 2 blank lines, found 1

The --statistics option gives you an overview of how many times a particular error happened. Here we have two PEP 8 violations, because flake8 expects two blank lines before a function definition instead of one. Go ahead and add an empty line before each functions definition. Run flake8 again to check that the error messages no longer appear.

--statistics选项使您可以概述特定错误发生了多少次。 在这里,我们有两个违反PEP 8的行为,因为flake8在函数定义之前需要两个空白行而不是一个。 继续并在每个函数定义之前添加一个空行。 再次运行flake8以检查错误消息是否不再出现。

Now it’s time to write the tests. Create a file called test_calculator.py in the top-level directory of your repository and copy the following code:

现在是时候编写测试了。 在存储库的顶级目录中创建一个名为test_calculator.py的文件,然后复制以下代码:

These tests make sure that our code works as expected. It is far from extensive because you haven’t tested for potential misuse of your code, but keep it simple for now.

这些测试确保我们的代码按预期工作。 它远非广泛,因为您尚未测试过可能滥用代码的情况,但现在就使其简单。

The following command runs your test:

以下命令运行您的测试:

 $ pytest -v --cov
$ pytest -v --cov
collected 2 items

collected 2 items

test_calculator.py::TestCalculator::test_addition PASSED [50%]

test_calculator.py::TestCalculator::test_addition PASSED [50%]

test_calculator.py::TestCalculator::test_subtraction PASSED [100%]

test_calculator.py::TestCalculator::test_subtraction PASSED [100%]

---------- coverage: platform darwin, python 3.6.6-final-0 -----------
---------- coverage: platform darwin, python 3.6.6-final-0 -----------
Name                                              Stmts   Miss  Cover
Name                                              Stmts   Miss  Cover
---------------------------------------------------------------------
---------------------------------------------------------------------
calculator.py                                         4      0   100%
calculator.py                                         4      0   100%
test_calculator.py                                    6      0   100%
test_calculator.py                                    6      0   100%
/Users/kristijan.ivancic/code/learn/__init__.py       0      0   100%
/Users/kristijan.ivancic/code/learn/__init__.py       0      0   100%
---------------------------------------------------------------------
---------------------------------------------------------------------
TOTAL                                                10      0   100%
TOTAL                                                10      0   100%

pytest is excellent at test discovery. Because you have a file with the prefix test, pytest knows it will contain unit tests for it to run. The same principles apply to the class and method names inside the file.

pytest在测试发现pytest非常出色。 因为您有一个带有前缀test的文件,所以pytest知道它将包含要运行的单元测试。 相同的原则适用于文件中的类和方法名称。

The -v flag gives you a nicer output, telling you which tests passed and which failed. In our case, both tests passed. The --cov flag makes sure pytest-cov runs and gives you a code coverage report for calculator.py.

-v标志为您提供了更好的输出,告诉您哪些测试通过了哪些失败了。 在我们的例子中,两个测试都通过了。 该--cov标志确保pytest-cov运行,并为你提供一个代码覆盖率报告calculator.py

You have completed the preparations. Commit the test file and push all those changes to the master branch:

您已完成准备工作。 提交测试文件,并将所有这些更改推送到master分支:

At the end of this section, your CalculatorLibrary folder should have the following files:

在本节的最后,您的CalculatorLibrary文件夹应包含以下文件:

CalculatorLibrary/
|
├── .git
├── .gitignore
├── README.md
├── calculator.py
├── requirements.txt
└── test_calculator.py
CalculatorLibrary/
|
├── .git
├── .gitignore
├── README.md
├── calculator.py
├── requirements.txt
└── test_calculator.py

Excellent, both your functions are tested and work correctly.

太好了,您的两个功能都经过测试,可以正常工作。

连接到CircleCI (Connect to CircleCI)

At last, you are ready to set up your continuous integration pipeline!

最后,您准备好建立持续集成管道!

CircleCI needs to know how to run your build and expects that information to be supplied in a particular format. It requires a .circleci folder within your repo and a configuration file inside it. A configuration file contains instructions for all the steps that the build server needs to execute. CircleCI expects this file to be called config.yml.

CircleCI需要知道如何运行您的构建,并希望以特定格式提供信息。 它在您的.circleci需要一个.circleci文件夹,并在其中需要一个配置文件。 配置文件包含有关构建服务器需要执行的所有步骤的说明。 CircleCI希望此文件名为config.yml

A .yml file uses a data serialization language, YAML, and it has its own specification. The goal of YAML is to be human readable and to work well with modern programming languages for common, everyday tasks.

.yml文件使用数据序列化语言YAML,并且具有自己的规范 。 YAML的目标是使人类可读并与现代编程语言很好地配合日常工作。

In a YAML file, there are three basic ways to represent data:

在YAML文件中,存在三种表示数据的基本方法:

  • Mappings (key-value pairs)
  • Sequences (lists)
  • Scalars (strings or numbers)
  • 映射(键值对)
  • 序列(列表)
  • 标量(字符串或数字)

It is very simple to read:

读起来很简单:

  • Indentation may be used for structure.
  • Colons separate key-value pairs.
  • Dashes are used to create lists.
  • 压痕可用于结构。
  • 冒号分隔键/值对。
  • 破折号用于创建列表。

Create the .circleci folder in your repo and a config.yml file with the following content:

在您的存储库中创建.circleci文件夹,并创建一个具有以下内容的config.yml文件:

Some of these words and concepts might be unfamiliar to you. For example, what is Docker, and what are images? Let’s go back in time a bit.

您可能不熟悉其中的某些单词和概念。 例如,什么是Docker?什么是映像? 让我们回到过去。

Remember the problem programmers face when something works on their laptop but nowhere else? Before, developers used to create a program that isolates a part of the computer’s physical resources (memory, hard drive, and so on) and turns them into a virtual machine.

还记得程序员在笔记本电脑上工作时遇到的问题吗? 以前,开发人员曾用来创建一个程序,该程序隔离计算机的一部分物理资源(内存,硬盘驱动器等),并将其转变为虚拟机

A virtual machine pretends to be a whole computer on its own. It would even have its own operating system. On that operating system, you deploy your application or install your library and test it.

虚拟机伪装成一台完整的计算机。 它甚至会有自己的操作系统。 在该操作系统上,您可以部署应用程序或安装库并对其进行测试。

Virtual machines take up a lot of resources, which sparked the invention of containers. The idea is analogous to shipping containers. Before shipping containers were invented, manufacturers had to ship goods in a wide variety of sizes, packaging, and modes (trucks, trains, ships).

虚拟机占用大量资源,这引发了容器的发明。 这个想法类似于运输集装箱。 在发明运输容器之前,制造商必须以各种尺寸,包装和方式(卡车,火车,轮船)运输货物。

By standardizing the shipping container, these goods could be transferred between different shipping methods without any modification. The same idea applies to software containers.

通过标准化运输容器,这些货物可以在不同的运输方法之间进行转移而无需任何修改。 同样的想法适用于软件容器。

Containers are a lightweight unit of code and its runtime dependencies, packaged in a standardized way, so they can quickly be plugged in and run on the Linux OS. You don’t need to create a whole virtual operating system, as you would with a virtual machine.

容器是轻量级的代码及其运行时依赖项的单位,以标准化方式打包,因此可以快速插入容器并在Linux OS上运行。 您无需像使用虚拟机那样创建整个虚拟操作系统。

Containers only replicate parts of the operating system they need in order to work. This reduces their size and gives them a big performance boost.

容器仅复制其工作所需的部分操作系统。 这减小了它们的尺寸,并极大地提高了性能。

Docker is currently the leading container platform, and it’s even able to run Linux containers on Windows and macOS. To create a Docker container, you need a Docker image. Images provide blueprints for containers much like classes provide blueprints for objects. You can read more about Docker in their Get Started guide.

Docker目前是领先的容器平台,它甚至能够在Windows和macOS上运行Linux容器。 要创建Docker容器,您需要一个Docker映像。 图像为容器提供了蓝图,就像类为对象提供了蓝图一样。 您可以在其《入门指南》中阅读有关Docker的更多信息。

CircleCI maintains pre-built Docker images for several programming languages. In the above configuration file, you have specified a Linux image that has Python already installed. That image will create a container in which everything else happens.

CircleCI为几种编程语言维护预构建的Docker映像 。 在上面的配置文件中,您指定了已安装Python的Linux映像。 该图像将创建一个容器,其中发生其他所有事情。

Let’s look at each line of the configuration file in turn:

让我们依次查看配置文件的每一行:

  1. version: Every config.yml starts with the CircleCI version number, used to issue warnings about breaking changes.

  2. jobs: Jobs represent a single execution of the build and are defined by a collection of steps. If you have only one job, it must be called build.

  3. build: As mentioned before, build is the name of your job. You can have multiple jobs, in which case they need to have unique names.

  4. docker: The steps of a job occur in an environment called an executor. The common executor in CircleCI is a Docker container. It is a cloud-hosted execution environment but other options exist, like a macOS environment.

  5. image: A Docker image is a file used to create a running Docker container. We are using an image that has Python 3.7 preinstalled.

  6. working_directory: Your repository has to be checked out somewhere on the build server. The working directory represents the file path where the repository will be stored.

  7. steps: This key marks the start of a list of steps to be performed by the build server.

  8. checkout: The first step the server needs to do is check the source code out to the working directory. This is performed by a special step called checkout.

  9. run: Executing command-line programs or commands is done inside the command key. The actual shell commands will be nested within.

  10. name: The CircleCI user interface shows you every build step in the form of an expandable section. The title of the section is taken from the value associated with the name key.

  11. command: This key represents the command to run via the shell. The | symbol specifices that what follows is a literal set of commands, one per line, exactly like you’d see in a shell/bash script.

  1. version每个config.yml以CircleCI版本号开头,用于发出有关更改更改的警告。

  2. jobs作业代表构建的单个执行,并由一系列步骤定义。 如果只有一项工作,则必须将其称为build

  3. build如前所述, build是您工作的名称。 您可以有多个作业,在这种情况下,它们需要具有唯一的名称。

  4. docker作业的步骤发生在称为执行程序的环境中。 CircleCI中的常见执行程序是Docker容器 。 它是一个由云托管的执行环境,但存在其他选项,例如macOS环境。

  5. image Docker映像是用于创建正在运行的Docker容器的文件。 我们正在使用预先安装了Python 3.7的映像。

  6. working_directory必须在构建服务器上的某个位置检出您的存储库。 工作目录表示将存储库的文件路径。

  7. steps此键标志着构建服务器要执行的步骤列表的开始。

  8. checkout服务器需要做的第一步是将源代码检出到工作目录中。 这是通过称为checkout的特殊步骤执行的。

  9. run执行命令行程序或命令是在command键内完成的。 实际的shell命令将嵌套在其中。

  10. name CircleCI用户界面以可扩展部分的形式向您显示每个构建步骤。 该部分的标题取自与name键关联的值。

  11. command此键代表通过外壳运行的命令。 | 后面的符号说明是一组文字命令,每行一个,与在shell / bash脚本中看到的完全一样。

You can read the CircleCI configuration reference document for more information.

您可以阅读CircleCI配置参考文档以获取更多信息。

Our pipeline is very simple and consists of 3 steps:

我们的管道非常简单,包括3个步骤:

  1. Checking out the repository
  2. Installing the dependencies in a virtual environment
  3. Running the linter and tests while inside the virtual environment
  1. 检出存储库
  2. 在虚拟环境中安装依赖项
  3. 在虚拟环境中运行Linter并进行测试

We now have everything we need to start our pipeline. Log in to your CircleCI account and click on Add Projects. Find your CalculatorLibrary repo and click Set Up Project. Select Python as your language. Since we already have a config.yml, we can skip the next steps and click Start building.

现在,我们拥有启动管道所需的一切。 登录到您的CircleCI帐户,然后单击“添加项目”。 找到您的CalculatorLibrary存储库,然后单击“设置项目”。 选择Python作为您的语言。 由于我们已经有了config.yml ,因此可以跳过以下步骤,然后单击“开始构建”。

CircleCI will take you to the execution dashboard for your job. If you followed all the steps correctly, you should see your job succeed.

CircleCI将带您进入工作的执行仪表板。 如果正确执行了所有步骤,则应该看到您的工作成功。

The final version of your CalculatorLibrary folder should look like this:

您的CalculatorLibrary文件夹的最终版本应如下所示:

CalculatorRepository/
|
├── .circleci
├── .git
├── .gitignore
├── README.md
├── calculator.py
├── requirements.txt
└── test_calculator.py
CalculatorRepository/
|
├── .circleci
├── .git
├── .gitignore
├── README.md
├── calculator.py
├── requirements.txt
└── test_calculator.py

Congratulations! You have created your first continuous integration pipeline. Now, every time you push to the master branch, a job will be triggered. You can see a list of your current and past jobs by clicking on Jobs in the CircleCI sidebar.

恭喜你! 您已经创建了第一个连续集成管道。 现在,每次您推送到master分支时,都会触发一个作业。 通过单击CircleCI侧栏中的“作业”,您可以查看当前和过去的作业列表。

做出改变 (Make Changes)

Time to add multiplication to our calculator library.

是时候将乘法添加到我们的计算器库中了。

This time, we will first add a unit test without writing the function. Without the code, the test will fail, which will also fail the CircleCI job. Add the following code to the end of your test_calculator.py:

这次,我们将首先添加一个单元测试,而无需编写该函数。 没有代码,测试将失败,CircleCI作业也将失败。 将以下代码添加到test_calculator.py

Push the code to the master branch and see the job fail in CircleCI. This shows that continuous integration works and watches your back if you make a mistake.

将代码推送到master分支,并在CircleCI中看到作业失败。 这表明持续集成是有效的,如果您犯了错误,则可以给予支持。

Now add the code to calculator.py that will make the test pass:

现在,将代码添加到calculator.py ,以使测试通过:

 def def multiplymultiply (( first_termfirst_term , , second_termsecond_term ):
    ):
    return return first_term first_term * * second_term
second_term

Make sure there are two empty spaces between the multiplication function and the previous one, or else your code will fail the linter check.

确保乘法函数和上一个函数之间有两个空格,否则您的代码将使linter检查失败。

The job should be successful this time. This workflow of writing a failing test first and then adding the code to pass the test is called test driven development (TDD). It’s a great way to work because it makes you think about your code structure in advance.

这次工作应该成功。 首先编写失败的测试,然后添加代码以通过测试的工作流称为测试驱动开发 (TDD)。 这是一种很好的工作方式,因为它使您可以提前考虑代码结构。

Now try it on your own. Add a test for the division function, see it fail, and write the function to make the test pass.

现在,自行尝试。 为除法函数添加一个测试,看到它失败,然后编写该函数以使测试通过。

通知事项 (Notifications)

When working on big applications that have a lot of moving parts, it can take a while for the continuous integration job to run. Most teams set up a notification procedure to let them know if one of their jobs fail. They can continue working while waiting for the job to run.

在具有大量活动部件的大型应用程序上运行时,连续集成作业可能需要一段时间才能运行。 大多数团队都设置了通知程序,以通知他们是否其中一项工作失败。 他们可以在等待作业运行的同时继续工作。

The most popular options are:

最受欢迎的选项是:

  • Sending an email for each failed build
  • Sending failure notifications to a Slack channel
  • Displaying failures on a dashboard visible to everyone
  • 为每个失败的构建发送电子邮件
  • 将故障通知发送到Slack频道
  • 在所有人都可以看到的仪表板上显示故障

By default, CircleCI should send you an email when a job fails.

默认情况下,作业失败时,CircleCI应向您发送电子邮件。

下一步 (Next Steps)

You have understood the basics of continuous integration and practiced setting up a pipeline for a simple Python program. This is a big step forward in your journey as a developer. You might be asking yourself, “What now?”

您已经了解了持续集成的基础知识,并练习了为简单的Python程序设置管道。 这是您作为开发人员迈出的一大步。 您可能会问自己:“现在怎么办?”

To keep things simple, this tutorial skimmed over some big topics. You can grow your skill set immensely by spending some time going more in-depth into each subject. Here are some topics you can look into further.

为简单起见,本教程简要介绍了一些重要主题。 您可以花一些时间深入研究每个主题,从而极大地提高自己的技能。 以下是一些可以进一步研究的主题。

Git工作流程 (Git Workflows)

There is much more to Git than what you used here. Each developer team has a workflow tailored to their specific needs. Most of them include branching strategies and something called peer review. They make changes on branches separate from the master branch. When you want to merge those changes with master, other developers must first look at your changes and approve them before you’re allowed to merge.

Git比您在这里使用的功能要多得多。 每个开发人员团队都有适合其特定需求的工作流程。 其中大多数包括分支策略和称为同行评审的内容 。 它们在与master分支分开的分支上进行更改。 当您要将这些更改与master合并时,其他开发人员必须先查看您的更改并批准它们,然后才允许您合并。

Note: If you want to learn more about different workflows teams use, have a look at the tutorials on GitHub and BitBucket.

注意:如果您想了解有关团队使用的不同工作流的更多信息,请查看GitHubBitBucket上的教程。

If you want to sharpen your Git skills, we have an article called Advanced Git Tips for Python Developers.

如果您想提高您的Git技能,我们有一篇名为Python开发者的高级Git技巧的文章。

依赖管理和虚拟环境 (Dependency Management and Virtual Environments)

Apart from virtualenv, there are other popular package and environment managers. Some of them deal with just virtual environments, while some handle both package installation and environment management. One of them is Conda:

除了virtualenv之外,还有其他流行的软件包和环境管理器。 其中一些仅处理虚拟环境,而另一些则处理软件包安装和环境管理。 其中之一是Conda:

“Conda is an open source package management system and environment management system that runs on Windows, macOS, and Linux. Conda quickly installs, runs and updates packages and their dependencies. Conda easily creates, saves, loads and switches between environments on your local computer. It was designed for Python programs, but it can package and distribute software for any language.” (Source)

“ Conda是一个开源软件包管理系统和环境管理系统,可在Windows,macOS和Linux上运行。 Conda可以快速安装,运行和更新软件包及其依赖项。 Conda可以轻松地在本地计算机上的环境中创建,保存,加载和切换。 它是为Python程序设计的,但可以打包和分发适用于任何语言的软件。” ( 来源

Another option is Pipenv, a younger contender that is rising in popularity among application developers. Pipenv brings together pip and virtualenv into a single tool and uses a Pipfile instead of requirements.txt. Pipfiles offer deterministic environments and more security. This introduction doesn’t do it justice, so check out Pipenv: A Guide to the New Python Packaging Tool.

另一个选择是Pipenv ,这是一个年轻的竞争者,在应用程序开发人员中越来越受欢迎。 Pipenv将pipvirtualenv集成到一个工具中,并使用Pipfile而不是requirements.txt 。 Pipfile提供确定性环境和更高的安全性。 这篇介绍并不能说明一切,因此请查看Pipenv:新Python打包工具指南

测试中 (Testing)

Simple unit tests with pytest are only the tip of the iceberg. There’s a whole world out there to explore! Software can be tested on many levels, including integration testing, acceptance testing, regression testing, and so forth. To take your knowledge of testing Python code to the next level, head over to Getting Started With Testing in Python.

pytest进行简单的单元测试只是冰山一角。 有一个世界可以探索! 可以在多个级别上测试软件,包括集成测试,验收测试,回归测试等等。 要使您对测试Python代码的知识更进一步,请转到Python测试入门

打包 (Packaging)

In this tutorial, you started to build a library of functions for other developers to use in their project. You need to package that library into a format that is easy to distribute and install using, for example pip.

在本教程中,您开始构建一个函数库,供其他开发人员在他们的项目中使用。 您需要将该库打包成易于分发和使用的格式,例如pip

Creating an installable package requires a different layout and some additional files like __init__.py and setup.py. Read Python Application Layouts: A Reference for more information on structuring your code.

创建可安装的软件包需要不同的布局和一些其他文件,例如__init__.pysetup.py 。 阅读Python应用程序布局:参考 ,以获取有关代码结构的更多信息。

To learn how to turn your repository into an installable Python package, read Packaging Python Projects by the Python Packaging Authority.

要了解如何将您的存储库转换为可安装的Python包,请阅读Python Packaging Authority的 Packaging Python Projects

持续集成 (Continuous Integration)

You covered all the basics of CI in this tutorial, using a simple example of Python code. It’s common for the final step of a CI pipeline to create a deployable artifact. An artifact represents a finished, packaged unit of work that is ready to be deployed to users or included in complex products.

在本教程中,您使用一个简单的Python代码示例介绍了CI的所有基础知识。 CI管道的最后一步通常会创建可部署的工件 。 工件代表完成的打包工作单元,可以将其部署给用户或包含在复杂产品中。

For example, to turn your calculator library into a deployable artifact, you would organize it into an installable package. Finally, you would add a step in CircleCI to package the library and store that artifact where other processes can pick it up.

例如,要将计算器库变成可部署的构件,您可以将其组织成可安装的程序包。 最后,您将在CircleCI中添加一个步骤来打包库并将该工件存储在其他进程可以拾取的地方。

For more complex applications, you can create a workflow to schedule and connect multiple CI jobs into a single execution. Feel free to explore the CircleCI documentation.

对于更复杂的应用程序,您可以创建一个工作流来安排多个CI作业并将其连接到一个执行中。 随意探索CircleCI文档

持续部署 (Continuous Deployment)

You can think of continuous deployment as an extension of CI. Once your code is tested and built into a deployable artifact, it is deployed to production, meaning the live application is updated with your changes. One of the goals is to minimize lead time, the time elapsed between writing a new line of code and putting it in front of users.

您可以将持续部署视为CI的扩展。 一旦测试了代码并将其构建到可部署的工件中,就将其部署到生产环境中,这意味着实时应用程序将使用您的更改进行更新。 目标之一是最大程度地缩短交付周期,即缩短编写新代码行与将其呈现给用户之间的时间。

Note: To add a bit of confusion to the mix, the acronym CD is not unique. It can also mean Continuous Delivery, which is almost the same as continuous deployment but has a manual verification step between integration and deployment. You can integrate your code at any time but have to push a button to release it to the live application.

注意:为了使混淆更加混乱,首字母缩写CD不是唯一的。 这也可能意味着持续交付,这与持续部署几乎相同,但是在集成和部署之间具有手动验证步骤。 您可以随时集成代码,但必须按一下按钮才能将其发布到实时应用程序中。

Most companies use CI/CD in tandem, so it’s worth your time to learn more about Continuous Delivery/Deployment.

大多数公司串联使用CI / CD,因此值得您花更多时间来了解有关持续交付/部署的更多信息。

持续集成服务概述 (Overview of Continuous Integration Services)

You have used CircleCI, one of the most popular continuous integration services. However, this is a big market with a lot of strong contenders. CI products fall into two basic categories: remote and self-hosted services.

您已经使用了CircleCI,这是最受欢迎的持续集成服务之一。 但是,这是一个有许多强大竞争者的大市场。 CI产品分为两个基本类别:远程服务和自托管服务。

Jenkins is the most popular self-hosted solution. It is open-source and flexible, and the community has developed a lot of extensions.

Jenkins是最受欢迎的自托管解决方案。 它是开源的且灵活的,并且社区已经开发了许多扩展。

In terms of remote services, there are many popular options like TravisCI, CodeShip, and Semaphore. Big enterprises often have their custom solutions, and they sell them as a service, such as AWS CodePipeline, Microsoft Team Foundation Server, and Oracle’s Hudson.

在远程服务方面,有许多流行的选项,例如TravisCICodeShipSemaphore 。 大型企业通常拥有其自定义解决方案,并且将它们作为服务出售,例如AWS CodePipelineMicrosoft Team Foundation Server和Oracle的Hudson

Which option you choose depends on the platform and features you and your team need. For a more detailed breakdown, have a look at Best CI Software by G2Crowd.

您选择哪种选项取决于您和团队所需的平台和功能。 有关更详细的细分,请查看G2Crowd的Best CI Software

结论 (Conclusion)

With the knowledge from this tutorial under your belt, you can now answer the following questions:

掌握了本教程的知识,您现在可以回答以下问题:

  • What is continuous integration?
  • Why is continuous integration important?
  • What are the core practices of continuous integration?
  • How can I set up continuous integration for my Python project?
  • 什么是持续集成?
  • 为什么持续集成很重要?
  • 持续集成的核心实践是什么?
  • 如何为我的Python项目设置持续集成?

You have acquired a programming superpower! Understanding the philosophy and practice of continuous integration will make you a valuable member of any team. Awesome work!

您已获得编程超级大国! 了解持续集成的理念和实践将使您成为任何团队的宝贵成员。 很棒的工作!

翻译自: https://www.pybloggers.com/2018/11/continuous-integration-with-python-an-introduction/

python持续集成

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值