简体   繁体   English

对于 Rust,您如何在发布到 crate.io 之前执行平台测试?

[英]With Rust how do you perform platform testing before publishing to crate.io?

I'm working on a framework which I'm testing on my Mac .我正在开发一个正在我的Mac上测试的framework Eventually, I'll want to publish to crate.io .最后,我想发布到crate.io I'd like for that to not blow up as a result of poor platform testing.我希望它不会因为平台测试不佳而崩溃。 Is there a means to test on all, or at least most, of the current deployment platforms without direct access to those platforms?是否有一种方法可以在不直接访问这些平台的情况下测试所有或至少大多数当前部署平台? For example, I don't have access to a Windows box.例如,我无法访问Windows框。

If you host your code on github you can set up github actions to build and test your code on multiple platforms.如果您在 github 上托管您的代码,您可以设置 github 操作以在多个平台上构建和测试您的代码。

I have two sets of actions that run on my code.我有两组在我的代码上运行的操作。

  • one runs the tests, and clippy and checks rust fmt on Linux only for normal pushes and pull requests一个运行测试,并且 clippy 并检查rust fmt仅用于正常的推送和拉取请求
  • the other runs when setting a release branch and creates a release, runs tests and builds and uploads release binaries for windows, Linux and macOS.另一个在设置发布分支并创建发布时运行,运行测试并构建和上传 windows、Linux 和 macOS 的发布二进制文件。

You can see the full files in all their glory here .您可以在此处查看完整的文件。

But combining these and simplifying means that to get testing on every push and pull request you would create a file at .github/workflows/testing.yml like this (untested):但是结合这些并简化意味着要对每个推送和拉取请求进行测试,您将在.github/workflows/testing.yml中创建一个文件,如下所示(未经测试):

name: Run Tests

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build_matrix:
    name: Run tests for ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        name: [linux, windows, macos]
        include:
          - name: linux
            os: ubuntu-latest
          - name: windows
            os: windows-latest
          - name: macos
            os: macos-latest
    steps:
    - uses: actions/checkout@v1

    - uses: actions-rs/toolchain@v1
      with:
        profile: minimal
        toolchain: nightly
        override: true

    - name: Test
      run: cargo test

I actually do this in one of my projects, altbinutils .我实际上是在我的一个项目altbinutils中这样做的。 I use Github Actions.我使用 Github 操作。 What I test are:我测试的是:

  • tests for each platform每个平台的测试
  • builds for each platform为每个平台构建
  • coverage testing覆盖测试
  • format testing格式测试

I separate workflows of each platforms to different configuration files because (i) I don't want to have all failed when one fails and (ii) I actually want to present them separately as Shields badges on my README.md to provide comprehensive detail.我将每个平台的工作流程分离到不同的配置文件,因为 (i) 我不想在一个失败时全部失败,并且 (ii) 我实际上想在我的README.md它们作为 Shields 徽章单独呈现,以提供全面的细节。

You can see the workflows under .github/workflows directory, but again, let me share the configurations here because it might change in the future.您可以在.github/workflows目录下看到工作流程,但再次让我在这里分享配置,因为它可能会在未来发生变化。

Build Workflows建立工作流程

Build workflows ensure that your code will compile in the target platform but not that it works correctly .构建工作流确保您的代码将在目标平台上编译,但不能确保它正常工作

I have three separate workflows for builds.我有三个独立的构建工作流程。 These are:这些都是:

  • build.linux.yml
  • build.windows.yml
  • build.macos.yml

The contents are:内容是:

# build.linux.yml
name: build_linux

on: [push, pull_request]

jobs:
  Test:
    strategy:
      matrix:
        os: [ubuntu-latest]
        rust: [stable, beta]

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v1
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: ${{ matrix.rust }}
          override: true
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - uses: actions-rs/cargo@v1
        with:
          command: build

# build.windows.yml
name: build_windows

on: [push, pull_request]

jobs:
  Test:
    strategy:
      matrix:
        os: [windows-latest]
        rust: [stable]

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v1
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: ${{ matrix.rust }}
          override: true
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - uses: actions-rs/cargo@v1
        with:
          command: build

# build.macos.yml
name: build_macos

on: [push, pull_request]

jobs:
  Test:
    strategy:
      matrix:
        os: [macos-latest]
        rust: [stable]

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v1
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: ${{ matrix.rust }}
          override: true
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - uses: actions-rs/cargo@v1
        with:
          command: build

If you look carefully, you can see I set up stable and beta Rust matrix to ensure my code won't break in the future and only on Linux platform since doing that on others are kind of redundant.如果你仔细看,你会发现我设置了stablebeta Rust 矩阵,以确保我的代码将来不会中断,并且只在 Linux 平台上,因为在其他平台上这样做有点多余。

Test Workflows测试工作流程

Test workflows ensure that your code behaves correctly.测试工作流程确保您的代码行为正确。

I have three three separate workflows for each platform.我为每个平台设置了三个独立的工作流程。 Those are:那些是:

# test.linux.yml
name: test_linux

on: [push, pull_request]

jobs:
  Test:
    strategy:
      matrix:
        os: [ubuntu-latest]
        rust: [stable, beta]

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v1
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: ${{ matrix.rust }}
          override: true
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - uses: actions-rs/cargo@v1
        with:
          command: test
          args: --lib --workspace

# test.windows.yml
name: test_windows

on: [push, pull_request]

jobs:
  Test:
    strategy:
      matrix:
        os: [windows-latest]
        rust: [stable]

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v1
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: ${{ matrix.rust }}
          override: true
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - uses: actions-rs/cargo@v1
        with:
          command: test
          args: --lib --workspace -- --nocapture

# test.macos.yml
name: test_macos

on: [push, pull_request]

jobs:
  Test:
    strategy:
      matrix:
        os: [macos-latest]
        rust: [stable]

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v1
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: ${{ matrix.rust }}
          override: true
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - uses: actions-rs/cargo@v1
        with:
          command: test
          args: --lib --workspace -- --nocapture

The extra thing you can see in these configurations are --workspace flag, which will test all your workspace if you have submembers for your project.您可以在这些配置中看到的额外内容是--workspace标志,如果您的项目有子成员,它将测试您的所有工作区 In my case, I have separate apps live under subdirectories, which are actually members of the workspace.就我而言,我在子目录下有单独的应用程序,它们实际上是工作区的成员。

Also note that for Windows and MacOS, I have also added -- --nocapture flag, which will actually print out all logs and print statements on those platforms.另请注意,对于 Windows 和 MacOS,我还添加了-- --nocapture标志,它实际上会打印出这些平台上的所有日志和打印语句。 I feel quite confident about Linux but, for the other platforms, I am not.我对 Linux 很有信心,但对于其他平台,我不是。

Coverage Workflow覆盖工作流程

Coverage workflow runs tests and calculates the percentage of the lines of code that your tests actually hit.覆盖率工作流运行测试并计算测试实际命中的代码行的百分比。 Then it pushes the statistics to Codecov so that you can see comprehensive details.然后它将统计信息推送到Codecov ,以便您可以看到全面的详细信息。

I have only one workflow for that, which runs on Linux. Only one is enough because coverage on other platforms will lead to (roughly) the same results.我只有一个工作流程,它在 Linux 上运行。只有一个就足够了,因为在其他平台上的覆盖将导致(大致)相同的结果。

The workflow configuration file is:工作流配置文件是:

# coverage.yml
name: coverage

on: [push, pull_request]

jobs:
  Test:
    strategy:
      matrix:
        os: [ubuntu-latest]
        rust: [stable]

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v1
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: ${{ matrix.rust }}
          override: true
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - name: Generate Coverage
        run: |
          cargo install cargo-tarpaulin
          cargo tarpaulin --verbose --all-features --workspace --timeout 120 --out Xml
      - name: Upload Coverage
        uses: codecov/codecov-action@v1
        with:
          fail_ci_if_error: true

Format Workflow格式化工作流程

Format workflow tests if the code is well formatted on new pull requests.格式化工作流程测试代码在新拉取请求中的格式是否正确。 You can use it if you think someone else will contribute code to your codebase and you want to keep it clean and readable as much as possible.如果您认为其他人会为您的代码库贡献代码并且您希望尽可能保持它的清洁和可读性,则可以使用它。

The workflow configuration file is:工作流配置文件是:

# format.yml
name: format

on: [push, pull_request]

jobs:
  Test:
    strategy:
      matrix:
        os: [ubuntu-latest]
        rust: [stable]

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v1
      - uses: actions-rs/toolchain@v1
        with:
          profile: minimal
          toolchain: ${{ matrix.rust }}
          override: true
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
      - uses: actions-rs/cargo@v1
        with:
          command: fmt
          args: -- --check

Presenting the Results展示结果

You can present the results as badges using Shields .您可以使用Shields将结果显示为徽章。 I present them in a Markdown table as below:我将它们呈现在 Markdown 表中,如下所示:

|             | Build                                 | Test                                | Format                  | Coverage                    |
| ----------- | ------------------------------------- | ----------------------------------- | ----------------------- | --------------------------- |
| **Linux**   | ![linux build][linux_build_badge]     | ![linux test][linux_test_badge]     | ![format][format_badge] | ![coverage][coverage_badge] |
| **Windows** | ![windows build][windows_build_badge] | ![windows test][windows_test_badge] | -                       | -                           |
| **MacOS**   | ![macos build][macos_build_badge]     | ![macos test][macos_test_badge]     | -                       | -                           |

<!-- START BADGES -->

<!-- linux -->
[linux_build_badge]: https://img.shields.io/github/workflow/status/erayerdin/altbinutils/build_linux/master?logo=linux&logoColor=white&style=flat-square
[linux_test_badge]: https://img.shields.io/github/workflow/status/erayerdin/altbinutils/test_linux/master?logo=linux&logoColor=white&style=flat-square&label=test
[format_badge]: https://img.shields.io/github/workflow/status/erayerdin/altbinutils/format/master?logo=linux&logoColor=white&style=flat-square&label=format
[coverage_badge]: https://img.shields.io/codecov/c/github/erayerdin/altbinutils/master?style=flat-square&token=71P6IZY43W&logo=linux&logoColor=white

<!-- windows -->
[windows_build_badge]: https://img.shields.io/github/workflow/status/erayerdin/altbinutils/build_windows/master?logo=windows&logoColor=white&style=flat-square
[windows_test_badge]: https://img.shields.io/github/workflow/status/erayerdin/altbinutils/test_windows/master?logo=windows&logoColor=white&style=flat-square&label=test

<!-- macos -->
[macos_build_badge]: https://img.shields.io/github/workflow/status/erayerdin/altbinutils/build_macos/master?logo=apple&logoColor=white&style=flat-square
[macos_test_badge]: https://img.shields.io/github/workflow/status/erayerdin/altbinutils/test_macos/master?logo=apple&logoColor=white&style=flat-square&label=test

<!-- END BADGES -->

You can actually present the status of one of your workflow (to show if it succeeded or failed) by changing the URL below to your needs:您实际上可以通过根据需要更改下面的 URL 来显示您的工作流程之一的状态(以显示它是成功还是失败):

https://img.shields.io/github/workflow/status/[your-username]/[your-reponame]/[name-attr-of-config-file]/[branch]

This will generate a badge for you so that people can be sure your code is working or not.这将为您生成一个徽章,以便人们可以确定您的代码是否正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM