Add a simple convenience test task runner for VSCode (#15417)

diff --git a/.gitignore b/.gitignore
index 6f135de..3f4f6e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,7 +17,7 @@
 .idea/
 
 # Visual Studio Code related
-.vscode/
+.vscode/*
 
 # Flutter repo-specific
 /bin/cache/
@@ -79,6 +79,8 @@
 **/ios/Runner/GeneratedPluginRegistrant.*
 
 # Exceptions to above rules.
+!.vscode/tasks.json
+!.vscode/test.sh
 !**/ios/**/default.mode1v3
 !**/ios/**/default.mode2v3
 !**/ios/**/default.pbxuser
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..5d1b720
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,24 @@
+{
+  "version": "2.0.0",
+  "tasks": [
+    {
+      "command": "./.vscode/test.sh",
+      "windows": {
+        // TODO :S
+      },
+      "label": "test",
+      "type": "shell",
+      "group": {
+        "kind": "test",
+        "isDefault": true
+      },
+      "presentation": {
+        "echo": true,
+        "reveal": "always",
+        "focus": false,
+        "panel": "new"
+      },
+      "args": ["${relativeFile}"]
+    }
+  ]
+}
diff --git a/.vscode/test.sh b/.vscode/test.sh
new file mode 100755
index 0000000..f12301f
--- /dev/null
+++ b/.vscode/test.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+if [[ $# -ne 1 ]]; then
+  echo "Invalid test target arguments.
+
+Please invoke test from VSCode via the workbench.action.tasks.test command."
+  exit 1
+fi
+
+if [[ "$1" != *.dart ]]; then
+  echo "Only .dart files can be tested by task in this repo."
+  exit 1
+fi
+
+echo "Testing $1..."
+
+if [[ "$1" == packages/flutter/test/* ]]; then
+  cd packages/flutter
+  ../../bin/flutter test ../../$1
+elif [[ "$1" == packages/flutter_tools/test/* ]]; then
+  bin/cache/dart-sdk/bin/dart $1
+else
+  echo "No test task configured for $1.
+
+Please edit .vscode/test.sh to configure new test types."
+  exit 1
+fi