diff --git a/test/vue/components/AsyncComp.vue b/test/vue/components/AsyncComp.vue
new file mode 100644
index 000000000000..e03b40dae718
--- /dev/null
+++ b/test/vue/components/AsyncComp.vue
@@ -0,0 +1,9 @@
+
+
+
+ resolved
+
diff --git a/test/vue/components/AsyncWrapper.vue b/test/vue/components/AsyncWrapper.vue
new file mode 100644
index 000000000000..e75b49d02ea8
--- /dev/null
+++ b/test/vue/components/AsyncWrapper.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ fallback
+
+
+
diff --git a/test/vue/test/async.test.ts b/test/vue/test/async.test.ts
new file mode 100644
index 000000000000..fcbdf08cc8d8
--- /dev/null
+++ b/test/vue/test/async.test.ts
@@ -0,0 +1,29 @@
+import { nextTick } from 'vue'
+import { flushPromises, mount } from '@vue/test-utils'
+import AsyncWrapper from '../components/AsyncWrapper.vue'
+
+test('async component with suspense', async() => {
+ expect(AsyncWrapper).toBeTruthy()
+
+ let resolve: Function
+ // eslint-disable-next-line promise/param-names
+ const promise = new Promise(_resolve => resolve = _resolve)
+ const wrapper = mount(AsyncWrapper, {
+ props: {
+ promise,
+ },
+ })
+
+ await nextTick()
+
+ expect(wrapper.text()).toContain('fallback')
+
+ resolve()
+
+ await flushPromises()
+ await nextTick()
+ await nextTick()
+
+ const text = wrapper.text()
+ expect(text).toContain('resolved')
+})
diff --git a/test/vue/tsconfig.json b/test/vue/tsconfig.json
new file mode 100644
index 000000000000..c319333d3d7c
--- /dev/null
+++ b/test/vue/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "target": "esnext"
+ }
+}