diff --git a/pages/composition-api/reactivity/reactive/reactive.test.js b/pages/composition-api/reactivity/reactive/reactive.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..2dcb4176edd89889f3d7c75b14957b6bc81319c5
--- /dev/null
+++ b/pages/composition-api/reactivity/reactive/reactive.test.js
@@ -0,0 +1,36 @@
+const PAGE_PATH = '/pages/composition-api/reactivity/reactive/reactive'
+
+describe('reactive', () => {
+  if (process.env.uniTestPlatformInfo.startsWith('android')) {
+    let page = null
+    beforeAll(async () => {
+      page = await program.reLaunch(PAGE_PATH)
+      await page.waitFor('view')
+    })
+    it('basic', async () => {
+      const count = await page.$('#count')
+      expect(await count.text()).toBe('count: 0')
+
+      const objStr = await page.$('#obj-str')
+      expect(await objStr.text()).toBe('obj.str: default str')
+
+      const objNum = await page.$('#obj-num')
+      expect(await objNum.text()).toBe('obj.num: 0')
+
+      const objArr = await page.$('#obj-arr')
+      expect(await objArr.text()).toBe('obj.arr: ["a","b","c"]')
+
+      const updateBtn = await page.$('#update-btn')
+      await updateBtn.tap()
+
+      expect(await count.text()).toBe('count: 2')
+      expect(await objStr.text()).toBe('obj.str: new str')
+      expect(await objNum.text()).toBe('obj.num: 2')
+      expect(await objArr.text()).toBe('obj.arr: ["a","b","c","d"]')
+    })
+  } else {
+    it('other platform', () => {
+      expect(1).toBe(1)
+    })
+  }
+})
\ No newline at end of file
diff --git a/pages/composition-api/reactivity/reactive/reactive.uvue b/pages/composition-api/reactivity/reactive/reactive.uvue
index 16d02559507054724884d9aef9ed58c793d30c61..a71c5dcb8dba4d1421b48bef5a46b180a4c36d1c 100644
--- a/pages/composition-api/reactivity/reactive/reactive.uvue
+++ b/pages/composition-api/reactivity/reactive/reactive.uvue
@@ -1 +1,26 @@
- <template><view class="page">reactive</view></template>
\ No newline at end of file
+<template>
+  <view class="page">
+    <text id="count" class="uni-common-mb">count: {{ count }}</text>
+    <text id="obj-str" class="uni-common-mb">obj.str: {{obj['str']}}</text>
+    <text id="obj-num" class="uni-common-mb">obj.num: {{obj['num']}}</text>
+    <text id="obj-arr" class="uni-common-mb">obj.arr: {{obj['arr']}}</text>
+    <button id="update-btn" @click="update">update</button>
+  </view>
+</template>
+
+<script setup>
+  const count = ref(0)
+
+  const obj = reactive({
+    str: 'default str',
+    num: count,
+    arr: ['a', 'b', 'c']
+  })
+
+  const update = () => {
+    obj['str'] = 'new str';
+    obj['num'] = (obj['num'] as number) + 1
+    count.value++
+    (obj['arr'] as string[]).push('d')
+  }
+</script>
\ No newline at end of file