diff --git a/.github/workflows/test_tokio.yml b/.github/workflows/test_tokio.yml
new file mode 100644
index 00000000000..47b0efab86d
--- /dev/null
+++ b/.github/workflows/test_tokio.yml
@@ -0,0 +1,123 @@
+on:
+  push:
+    branches: ["master"]
+  pull_request:
+    branches: ["master"]
+
+name: Test tokio
+
+env:
+  RUSTFLAGS: -Dwarnings
+  RUST_BACKTRACE: 1
+  nightly: nightly-2020-01-25
+
+jobs:
+  test_tokio:
+    name: Test tokio full
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        os:
+          - windows-latest
+          - ubuntu-latest
+          - macos-latest
+    steps:
+      - uses: actions/checkout@master
+
+      # Run `tokio` with only `full`
+      - uses: actions-rs/cargo@v1
+        with:
+          command: test
+          args: --manifest-path ${{ github.workspace }}/tokio/Cargo.toml --features full
+        name: tokio - cargo test --features full
+
+      # Run `tokio` with "unstable" cfg flag
+      - uses: actions-rs/cargo@v1
+        with:
+          command: test
+          args: --manifest-path ${{ github.workspace }}/tokio/Cargo.toml --features full
+        env:
+          RUSTFLAGS: '--cfg tokio_unstable'
+        name: tokio - cargo test --features full --cfg tokio_unstable
+
+  test_cross_subcrates:
+    name: Test ${{ matrix.crate }} (${{ matrix.os }}) all-features
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        crate:
+          - tokio
+          - tests-integration
+        os:
+          - windows-latest
+          - ubuntu-latest
+          - macos-latest
+        include:
+          - crate: tokio-macros
+            os: ubuntu-latest
+          - crate: tokio-test
+            os: ubuntu-latest
+          - crate: tokio-util
+            os: ubuntu-latest
+          - crate: examples
+            os: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@master
+
+      # Run with all crate features
+      - name: ${{ matrix.crate }} - cargo test --all-features
+        uses: actions-rs/cargo@v1
+        with:
+          command: test
+          args: --manifest-path ${{ github.workspace }}/${{ matrix.crate }}/Cargo.toml --all-features
+
+        # Check benches
+      - name: ${{ matrix.crate }} - cargo check --benches
+        uses: actions-rs/cargo@v1
+        with:
+          command: check
+          args: --manifest-path ${{ github.workspace }}/${{ matrix.crate }}/Cargo.toml --all-features --benches
+
+      - name: Patch Cargo.toml
+        shell: bash
+        run: |
+          set -e
+
+          # Remove any existing patch statements
+          mv Cargo.toml Cargo.toml.bck
+          sed -n '/\[patch.crates-io\]/q;p' Cargo.toml.bck > Cargo.toml
+
+          # Patch all crates
+          cat ci/patch.toml >> Cargo.toml
+
+          # Print `Cargo.toml` for debugging
+          echo "~~~~ Cargo.toml ~~~~"
+          cat Cargo.toml
+          echo "~~~~~~~~~~~~~~~~~~~~"
+
+      # Run with all crate features
+      - name: ${{ matrix.crate }} - cargo test --all-features
+        uses: actions-rs/cargo@v1
+        with:
+          command: test
+          args: --manifest-path ${{ github.workspace }}/${{ matrix.crate }}/Cargo.toml --all-features
+
+  test_integration:
+    name: Integration tests
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        os:
+          - windows-latest
+          - ubuntu-latest
+          - macos-latest
+    steps:
+      - uses: actions/checkout@master
+      - run: cargo install cargo-hack
+        name: Install cargo-hack
+      - uses: actions-rs/cargo@v1
+        name: cargo hack test --each-feature
+        with:
+          command: hack
+          args: test --manifest-path ${{ github.workspace }}/tests-integration/Cargo.toml --each-feature