diff --git a/python3/testcase/python3-builtin-functions.sh b/python3/testcase/python3-builtin-functions.sh new file mode 100755 index 0000000000000000000000000000000000000000..bf7a2e0cc5438ad5c0c7f85b5c300502ecf9c420 --- /dev/null +++ b/python3/testcase/python3-builtin-functions.sh @@ -0,0 +1,145 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-560602275 +# @用例名称: python3-builtin-functions +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 内置函数的正确性,包括 len、range、sorted、min、max、sum、abs、round、type、isinstance 等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 测试 len() 内置函数 + # @预期结果: 正确返回字符串和列表的长度 + python3 -c "print(len('hello')); print(len([1,2,3]))" > "$g_tmpdir/len.out" 2>&1 + ret=$? + msg "CHECK: len() 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "5" "$g_tmpdir/len.out" + assert_true grep -q "3" "$g_tmpdir/len.out" + + # @测试步骤: 测试 sorted() 内置函数 + # @预期结果: 列表正确排序 + python3 -c "print(sorted([3,1,4,1,5,9]))" > "$g_tmpdir/sorted.out" 2>&1 + ret=$? + msg "CHECK: sorted() 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "\[1, 1, 3, 4, 5, 9\]" "$g_tmpdir/sorted.out" + + # @测试步骤: 测试 min() 和 max() 内置函数 + # @预期结果: 正确返回最小值和最大值 + python3 -c "nums = [10, 20, 5, 30]; print(min(nums)); print(max(nums))" > "$g_tmpdir/minmax.out" 2>&1 + ret=$? + msg "CHECK: min/max() 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "5" "$g_tmpdir/minmax.out" + assert_true grep -q "30" "$g_tmpdir/minmax.out" + + # @测试步骤: 测试 sum() 内置函数 + # @预期结果: 正确计算列表元素之和 + python3 -c "print(sum([1, 2, 3, 4, 5]))" > "$g_tmpdir/sum.out" 2>&1 + ret=$? + msg "CHECK: sum() 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "15" "$g_tmpdir/sum.out" + + # @测试步骤: 测试 abs() 内置函数 + # @预期结果: 正确返回绝对值 + python3 -c "print(abs(-42)); print(abs(42))" > "$g_tmpdir/abs.out" 2>&1 + ret=$? + msg "CHECK: abs() 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "42" "$g_tmpdir/abs.out" + + # @测试步骤: 测试 round() 内置函数 + # @预期结果: 正确进行四舍五入 + python3 -c "print(round(3.7)); print(round(3.2)); print(round(2.5))" > "$g_tmpdir/round.out" 2>&1 + ret=$? + msg "CHECK: round() 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "4" "$g_tmpdir/round.out" + + # @测试步骤: 测试 type() 内置函数 + # @预期结果: 正确返回对象类型 + python3 -c "print(type(42)); print(type('hello')); print(type([1,2]))" > "$g_tmpdir/type.out" 2>&1 + ret=$? + msg "CHECK: type() 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "int" "$g_tmpdir/type.out" + assert_true grep -q "str" "$g_tmpdir/type.out" + assert_true grep -q "list" "$g_tmpdir/type.out" + + # @测试步骤: 测试 isinstance() 内置函数 + # @预期结果: 正确判断对象类型 + python3 -c "print(isinstance(42, int)); print(isinstance('hi', str)); print(isinstance(3.14, int))" > "$g_tmpdir/instance.out" 2>&1 + ret=$? + msg "CHECK: isinstance() 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "True" "$g_tmpdir/instance.out" + assert_true grep -q "False" "$g_tmpdir/instance.out" + + # @测试步骤: 测试 range() 和 enumerate() 内置函数 + # @预期结果: 正确生成序列和带索引的枚举 + python3 -c "print(list(range(3))); print(list(enumerate(['a','b'])))" > "$g_tmpdir/range_enum.out" 2>&1 + ret=$? + msg "CHECK: range/enumerate() 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "\[0, 1, 2\]" "$g_tmpdir/range_enum.out" + assert_true grep -q "(0, 'a')" "$g_tmpdir/range_enum.out" + + # @测试步骤: 测试 zip() 和 dict() 内置函数 + # @预期结果: 正确合并列表并创建字典 + python3 -c "keys = ['a','b']; vals = [1,2]; print(dict(zip(keys, vals)))" > "$g_tmpdir/zip.out" 2>&1 + ret=$? + msg "CHECK: zip/dict() 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "{'a': 1, 'b': 2}" "$g_tmpdir/zip.out" + + # @测试步骤: 测试 map() 和 filter() 内置函数 + # @预期结果: 正确映射和过滤列表元素 + python3 -c "print(list(map(lambda x: x*2, [1,2,3]))); print(list(filter(lambda x: x>2, [1,2,3,4])))" > "$g_tmpdir/mapfilter.out" 2>&1 + ret=$? + msg "CHECK: map/filter() 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "\[2, 4, 6\]" "$g_tmpdir/mapfilter.out" + assert_true grep -q "\[3, 4\]" "$g_tmpdir/mapfilter.out" + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-c-command-execution.sh b/python3/testcase/python3-c-command-execution.sh new file mode 100755 index 0000000000000000000000000000000000000000..94f8fb42cdf95d244770a7fb2a82adee593936ad --- /dev/null +++ b/python3/testcase/python3-c-command-execution.sh @@ -0,0 +1,119 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-505793112 +# @用例名称: python3-c-command-execution +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 -c 选项能够正确执行单行 Python 代码,包括算术运算、字符串处理、列表操作和条件判断 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 使用 python3 -c 执行基本算术运算 + # @预期结果: 输出正确的计算结果 42 + python3 -c "print(6 * 7)" > "$g_tmpdir/arithmetic.out" 2>&1 + ret=$? + msg "CHECK: 算术运算返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + msg "CHECK: 算术运算结果, 实际值=$(cat "$g_tmpdir/arithmetic.out")" + assert_true grep -q "42" "$g_tmpdir/arithmetic.out" + + # @测试步骤: 使用 python3 -c 执行字符串拼接和格式化 + # @预期结果: 输出格式化后的字符串 Hello World + python3 -c "print('Hello ' + 'World')" > "$g_tmpdir/string.out" 2>&1 + ret=$? + msg "CHECK: 字符串拼接返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "Hello World" "$g_tmpdir/string.out" + + # @测试步骤: 使用 python3 -c 执行列表创建和索引访问 + # @预期结果: 输出列表的第三个元素 cherry + python3 -c "fruits = ['apple', 'banana', 'cherry']; print(fruits[2])" > "$g_tmpdir/list.out" 2>&1 + ret=$? + msg "CHECK: 列表操作返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "cherry" "$g_tmpdir/list.out" + + # @测试步骤: 使用 python3 -c 执行字典操作 + # @预期结果: 输出字典中 key 对应的值 Alice + python3 -c "d = {'name': 'Alice', 'age': 30}; print(d['name'])" > "$g_tmpdir/dict.out" 2>&1 + ret=$? + msg "CHECK: 字典操作返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "Alice" "$g_tmpdir/dict.out" + + # @测试步骤: 使用 python3 -c 执行条件判断 + # @预期结果: 输出 even(偶数判断) + python3 -c "x = 10; print('even' if x % 2 == 0 else 'odd')" > "$g_tmpdir/condition.out" 2>&1 + ret=$? + msg "CHECK: 条件判断返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "even" "$g_tmpdir/condition.out" + + # @测试步骤: 使用 python3 -c 执行循环操作 + # @预期结果: 输出 0 1 2 3 4(range 循环) + python3 -c "print(' '.join(str(i) for i in range(5)))" > "$g_tmpdir/loop.out" 2>&1 + ret=$? + msg "CHECK: 循环操作返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "0 1 2 3 4" "$g_tmpdir/loop.out" + + # @测试步骤: 使用 python3 -c 执行函数定义和调用 + # @预期结果: 输出函数返回值 25 + python3 -c " +def square(x): + return x * x +print(square(5)) +" > "$g_tmpdir/func.out" 2>&1 + ret=$? + msg "CHECK: 函数调用返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "25" "$g_tmpdir/func.out" + + # @测试步骤: 使用 python3 -c 执行浮点数运算 + # @预期结果: 输出结果包含 3.14 + python3 -c "import math; print(round(math.pi, 2))" > "$g_tmpdir/float.out" 2>&1 + ret=$? + msg "CHECK: 浮点运算返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "3.14" "$g_tmpdir/float.out" + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-data-types.sh b/python3/testcase/python3-data-types.sh new file mode 100755 index 0000000000000000000000000000000000000000..6acd1167c5eb985ad46991be0ae959166e0cb652 --- /dev/null +++ b/python3/testcase/python3-data-types.sh @@ -0,0 +1,180 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-586602813 +# @用例名称: python3-data-types +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 核心数据类型的操作正确性,包括整数、浮点数、字符串、列表、元组、字典、集合和布尔值 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 测试整数类型运算(加减乘除、取模、幂运算) + # @预期结果: 各种整数运算结果正确 + python3 -c " +a, b = 17, 5 +print(f'add={a+b}') +print(f'sub={a-b}') +print(f'mul={a*b}') +print(f'div={a//b}') +print(f'mod={a%b}') +print(f'pow={a**b}') +" > "$g_tmpdir/int.out" 2>&1 + ret=$? + msg "CHECK: 整数运算返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "add=22" "$g_tmpdir/int.out" + assert_true grep -q "mul=85" "$g_tmpdir/int.out" + assert_true grep -q "pow=1419857" "$g_tmpdir/int.out" + + # @测试步骤: 测试浮点数类型运算 + # @预期结果: 浮点数运算和精度处理正确 + python3 -c " +a, b = 3.14, 2.0 +print(f'sum={a+b}') +print(f'prod={a*b}') +print(f'true_div={a/b}') +print(f'is_float={isinstance(a, float)}') +" > "$g_tmpdir/float.out" 2>&1 + ret=$? + msg "CHECK: 浮点运算返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "sum=5.14" "$g_tmpdir/float.out" + assert_true grep -q "is_float=True" "$g_tmpdir/float.out" + + # @测试步骤: 测试列表类型操作(增删改查、切片、排序) + # @预期结果: 列表各项操作结果正确 + python3 -c " +lst = [3, 1, 4, 1, 5] +lst.append(9) +lst.remove(1) +print(f'len={len(lst)}') +print(f'slice={lst[1:4]}') +print(f'sorted={sorted(lst)}') +print(f'reversed={lst[::-1]}') +lst[0] = 10 +print(f'modified={lst}') +" > "$g_tmpdir/list.out" 2>&1 + ret=$? + msg "CHECK: 列表操作返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "len=5" "$g_tmpdir/list.out" + assert_true grep -q "sorted=" "$g_tmpdir/list.out" + + # @测试步骤: 测试元组类型操作(创建、解包、嵌套) + # @预期结果: 元组操作正确,不可变性得到验证 + python3 -c " +t = (1, 2, 3) +a, b, c = t +print(f'unpack={a},{b},{c}') +print(f'count={t.count(1)}') +print(f'index={t.index(3)}') +nested = (1, (2, 3), 4) +print(f'nested={nested[1]}') +try: + t[0] = 99 + print('mutable=True') +except TypeError: + print('immutable=True') +" > "$g_tmpdir/tuple.out" 2>&1 + ret=$? + msg "CHECK: 元组操作返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "unpack=1,2,3" "$g_tmpdir/tuple.out" + assert_true grep -q "immutable=True" "$g_tmpdir/tuple.out" + + # @测试步骤: 测试字典类型操作(增删改查、遍历、方法) + # @预期结果: 字典各项操作结果正确 + python3 -c " +d = {'name': 'Python', 'version': '3'} +d['year'] = '1991' +del d['year'] +print(f'keys={sorted(d.keys())}') +print(f'values={sorted(d.values())}') +print(f'get={d.get(\"name\")}') +print(f'len={len(d)}') +print(f'contains={\"version\" in d}') +" > "$g_tmpdir/dict.out" 2>&1 + ret=$? + msg "CHECK: 字典操作返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "Python" "$g_tmpdir/dict.out" + assert_true grep -q "contains=True" "$g_tmpdir/dict.out" + + # @测试步骤: 测试集合类型操作(并集、交集、差集、子集) + # @预期结果: 集合运算结果正确 + python3 -c " +a = {1, 2, 3, 4} +b = {3, 4, 5, 6} +print(f'union={sorted(a | b)}') +print(f'intersect={sorted(a & b)}') +print(f'diff={sorted(a - b)}') +print(f'subset={ {1,2} < a }') +print(f'unique={len({1,1,2,2,3})}') +" > "$g_tmpdir/set.out" 2>&1 + ret=$? + msg "CHECK: 集合操作返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "union=" "$g_tmpdir/set.out" + assert_true grep -q "intersect=" "$g_tmpdir/set.out" + assert_true grep -q "subset=True" "$g_tmpdir/set.out" + + # @测试步骤: 测试布尔类型和比较运算 + # @预期结果: 布尔值和比较运算正确 + python3 -c " +print(f'true={True}') +print(f'false={False}') +print(f'and_op={True and False}') +print(f'or_op={True or False}') +print(f'not_op={not True}') +print(f'eq={1 == 1}') +print(f'ne={1 != 2}') +print(f'bool_int={bool(1)}') +print(f'bool_zero={bool(0)}') +" > "$g_tmpdir/bool.out" 2>&1 + ret=$? + msg "CHECK: 布尔运算返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "and_op=False" "$g_tmpdir/bool.out" + assert_true grep -q "or_op=True" "$g_tmpdir/bool.out" + assert_true grep -q "eq=True" "$g_tmpdir/bool.out" + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-error-handling.sh b/python3/testcase/python3-error-handling.sh new file mode 100755 index 0000000000000000000000000000000000000000..0d8086159c6dfe4252b8d6e4bac5bfdebc3c871c --- /dev/null +++ b/python3/testcase/python3-error-handling.sh @@ -0,0 +1,205 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-640079691 +# @用例名称: python3-error-handling +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 异常处理机制的正确性,包括 try-except、多重异常捕获、finally 块、自定义异常和 raise 语句 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 测试基本 try-except 捕获 ZeroDivisionError + # @预期结果: 异常被正确捕获,输出错误信息 + python3 -c " +try: + result = 1 / 0 +except ZeroDivisionError as e: + print(f'caught={type(e).__name__}') + print(f'message={str(e)}') +" > "$g_tmpdir/division.out" 2>&1 + ret=$? + msg "CHECK: 除零异常捕获返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "caught=ZeroDivisionError" "$g_tmpdir/division.out" + + # @测试步骤: 测试 try-except 捕获 KeyError + # @预期结果: 字典键不存在异常被正确捕获 + python3 -c " +try: + d = {'a': 1} + print(d['b']) +except KeyError as e: + print(f'caught_KeyError=True') + print(f'missing_key={e}') +" > "$g_tmpdir/keyerror.out" 2>&1 + ret=$? + msg "CHECK: KeyError捕获返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "caught_KeyError=True" "$g_tmpdir/keyerror.out" + + # @测试步骤: 测试 try-except 捕获 TypeError + # @预期结果: 类型错误被正确捕获 + python3 -c " +try: + result = 'str' + 123 +except TypeError as e: + print(f'caught_TypeError=True') +" > "$g_tmpdir/typeerror.out" 2>&1 + ret=$? + msg "CHECK: TypeError捕获返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "caught_TypeError=True" "$g_tmpdir/typeerror.out" + + # @测试步骤: 测试多重异常捕获(except 多个类型) + # @预期结果: 不同异常类型被正确分类捕获 + python3 -c " +def process(val): + try: + return int(val) * 2 + except (ValueError, TypeError) as e: + return f'error={type(e).__name__}' + +print(f'valid={process(\"42\")}') +print(f'invalid={process(\"abc\")}') +print(f'none={process(None)}') +" > "$g_tmpdir/multi_except.out" 2>&1 + ret=$? + msg "CHECK: 多重异常捕获返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "valid=84" "$g_tmpdir/multi_except.out" + assert_true grep -q "error=ValueError" "$g_tmpdir/multi_except.out" + + # @测试步骤: 测试 try-except-else-finally 完整结构 + # @预期结果: else 和 finally 块按预期执行 + python3 -c " +def safe_divide(a, b): + try: + result = a / b + except ZeroDivisionError: + print('except_block') + return None + else: + print('else_block') + return result + finally: + print('finally_block') + +print(f'result1={safe_divide(10, 2)}') +print(f'result2={safe_divide(10, 0)}') +" > "$g_tmpdir/finally.out" 2>&1 + ret=$? + msg "CHECK: finally块返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "else_block" "$g_tmpdir/finally.out" + assert_true grep -q "finally_block" "$g_tmpdir/finally.out" + assert_true grep -q "except_block" "$g_tmpdir/finally.out" + + # @测试步骤: 测试自定义异常类 + # @预期结果: 自定义异常被正确定义、抛出和捕获 + python3 -c " +class CustomError(Exception): + def __init__(self, code, message): + self.code = code + self.message = message + def __str__(self): + return f'CustomError({self.code}): {self.message}' + +try: + raise CustomError(500, 'Internal error') +except CustomError as e: + print(f'caught_custom=True') + print(f'code={e.code}') + print(f'msg={e.message}') +" > "$g_tmpdir/custom_exc.out" 2>&1 + ret=$? + msg "CHECK: 自定义异常返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "caught_custom=True" "$g_tmpdir/custom_exc.out" + assert_true grep -q "code=500" "$g_tmpdir/custom_exc.out" + + # @测试步骤: 测试 raise 语句重新抛出异常 + # @预期结果: 异常被捕获后重新抛出,外层能再次捕获 + python3 -c " +def inner(): + raise ValueError('original error') + +def outer(): + try: + inner() + except ValueError as e: + print(f'inner_caught=True') + raise RuntimeError('wrapped') from e + +try: + outer() +except RuntimeError as e: + print(f'outer_caught=True') + print(f'cause={type(e.__cause__).__name__}') +" > "$g_tmpdir/reraise.out" 2>&1 + ret=$? + msg "CHECK: 重新抛出异常返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "inner_caught=True" "$g_tmpdir/reraise.out" + assert_true grep -q "outer_caught=True" "$g_tmpdir/reraise.out" + assert_true grep -q "cause=ValueError" "$g_tmpdir/reraise.out" + + # @测试步骤: 测试 assert 语句 + #预期结果: assert 条件满足时不报错,不满足时抛出 AssertionError + python3 -c " +# 正常情况 +assert 1 + 1 == 2, 'math works' +print('assert_pass=True') + +# 失败情况 +try: + assert 1 + 1 == 3, 'math broken' +except AssertionError as e: + print(f'assert_fail=True') + print(f'msg={e}') +" > "$g_tmpdir/assert.out" 2>&1 + ret=$? + msg "CHECK: assert语句返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "assert_pass=True" "$g_tmpdir/assert.out" + assert_true grep -q "assert_fail=True" "$g_tmpdir/assert.out" + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-file-io.sh b/python3/testcase/python3-file-io.sh new file mode 100755 index 0000000000000000000000000000000000000000..4abc824af1c217ceadace285c49b2680668decc6 --- /dev/null +++ b/python3/testcase/python3-file-io.sh @@ -0,0 +1,168 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-613395116 +# @用例名称: python3-file-io +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 文件读写操作的正确性,包括文本文件读写、二进制文件读写、with 语句、文件追加和目录操作 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" +g_testfile="$g_tmpdir/test.txt" +g_binfile="$g_tmpdir/test.bin" +g_apdfile="$g_tmpdir/append.txt" +g_testdir="$g_tmpdir/testdir" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + # @预置条件: 创建测试目录 + mkdir -p "$g_testdir" + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 使用 open() 写入文本文件并读取验证 + # @预期结果: 文件写入成功,读取内容与写入内容一致 + python3 -c " +with open('$g_testfile', 'w') as f: + f.write('Line 1: Hello\n') + f.write('Line 2: World\n') + f.write('Line 3: Python3\n') +with open('$g_testfile', 'r') as f: + content = f.read() +print(content) +" > "$g_tmpdir/write_read.out" 2>&1 + ret=$? + msg "CHECK: 文件读写返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "Line 1: Hello" "$g_tmpdir/write_read.out" + assert_true grep -q "Line 3: Python3" "$g_tmpdir/write_read.out" + + # @测试步骤: 使用 with 语句逐行读取文件 + # @预期结果: 逐行读取正确,行数和行数统计正确 + python3 -c " +lines = [] +with open('$g_testfile', 'r') as f: + for line in f: + lines.append(line.strip()) +print(f'count={len(lines)}') +for i, line in enumerate(lines): + print(f'line{i}={line}') +" > "$g_tmpdir/line_read.out" 2>&1 + ret=$? + msg "CHECK: 逐行读取返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "count=3" "$g_tmpdir/line_read.out" + assert_true grep -q "line0=Line 1: Hello" "$g_tmpdir/line_read.out" + + # @测试步骤: 使用追加模式向文件追加内容 + # @预期结果: 原内容保留,新内容追加到文件末尾 + echo "original content" > "$g_apdfile" + python3 -c " +with open('$g_apdfile', 'a') as f: + f.write('appended line 1\n') + f.write('appended line 2\n') +with open('$g_apdfile', 'r') as f: + content = f.read() +print(content) +" > "$g_tmpdir/append.out" 2>&1 + ret=$? + msg "CHECK: 文件追加返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "original content" "$g_tmpdir/append.out" + assert_true grep -q "appended line 2" "$g_tmpdir/append.out" + + # @测试步骤: 使用二进制模式写入和读取文件 + # @预期结果: 二进制数据正确写入和读取 + python3 -c " +data = bytes([0x48, 0x65, 0x6c, 0x6c, 0x6f]) +with open('$g_binfile', 'wb') as f: + f.write(data) +with open('$g_binfile', 'rb') as f: + read_data = f.read() +print(f'written={len(data)}') +print(f'read={len(read_data)}') +print(f'match={data == read_data}') +print(f'decoded={read_data.decode()}') +" > "$g_tmpdir/binary.out" 2>&1 + ret=$? + msg "CHECK: 二进制读写返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "match=True" "$g_tmpdir/binary.out" + assert_true grep -q "decoded=Hello" "$g_tmpdir/binary.out" + + # @测试步骤: 使用 os 模块进行目录和文件操作 + # @预期结果: 目录创建、文件存在性检查、文件列表正确 + python3 -c " +import os +testdir = '$g_testdir' +os.makedirs(os.path.join(testdir, 'subdir'), exist_ok=True) +with open(os.path.join(testdir, 'file1.txt'), 'w') as f: + f.write('test') +with open(os.path.join(testdir, 'subdir', 'file2.txt'), 'w') as f: + f.write('test2') +print(f'dir_exists={os.path.isdir(testdir)}') +print(f'file_exists={os.path.isfile(os.path.join(testdir, \"file1.txt\"))}') +print(f'files={sorted(os.listdir(testdir))}') +print(f'all_files={sorted(os.listdir(os.path.join(testdir, \"subdir\")))}') +" > "$g_tmpdir/dir_op.out" 2>&1 + ret=$? + msg "CHECK: 目录操作返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "dir_exists=True" "$g_tmpdir/dir_op.out" + assert_true grep -q "file_exists=True" "$g_tmpdir/dir_op.out" + + # @测试步骤: 使用 json 模块读写 JSON 文件 + # @预期结果: JSON 数据正确序列化和反序列化 + python3 -c " +import json +data = {'name': 'test', 'values': [1, 2, 3], 'nested': {'key': 'val'}} +with open('$g_tmpdir/data.json', 'w') as f: + json.dump(data, f, indent=2) +with open('$g_tmpdir/data.json', 'r') as f: + loaded = json.load(f) +print(f'type={type(loaded).__name__}') +print(f'name={loaded[\"name\"]}') +print(f'values={loaded[\"values\"]}') +print(f'match={data == loaded}') +" > "$g_tmpdir/json_io.out" 2>&1 + ret=$? + msg "CHECK: JSON读写返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "type=dict" "$g_tmpdir/json_io.out" + assert_true grep -q "match=True" "$g_tmpdir/json_io.out" + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-import-standard-modules.sh b/python3/testcase/python3-import-standard-modules.sh new file mode 100755 index 0000000000000000000000000000000000000000..106579edbe6ac479f586df41945a701ba4e156fe --- /dev/null +++ b/python3/testcase/python3-import-standard-modules.sh @@ -0,0 +1,219 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-666566220 +# @用例名称: python3-import-standard-modules +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 标准库模块的导入和功能正确性,包括 os、sys、json、math、datetime、collections、re、hashlib、random、pathlib 等 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 测试 os 和 sys 模块导入和基本功能 + # @预期结果: 模块导入成功,能获取系统信息 + python3 -c " +import os +import sys +print(f'os_name={os.name}') +print(f'cwd_exists={os.path.exists(\".\")}') +print(f'python_version={sys.version_info.major}.{sys.version_info.minor}') +print(f'platform={sys.platform}') +print(f'path_count={len(sys.path)}') +" > "$g_tmpdir/os_sys.out" 2>&1 + ret=$? + msg "CHECK: os/sys模块返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "os_name=posix" "$g_tmpdir/os_sys.out" + assert_true grep -q "platform=linux" "$g_tmpdir/os_sys.out" + + # @测试步骤: 测试 json 模块导入和编解码功能 + # @预期结果: JSON 数据正确序列化和反序列化 + python3 -c " +import json +data = {'key': 'value', 'numbers': [1, 2, 3]} +encoded = json.dumps(data) +decoded = json.loads(encoded) +print(f'encoded_type={type(encoded).__name__}') +print(f'decoded_match={data == decoded}') +pretty = json.dumps(data, indent=2) +print(f'pretty_has_indent={chr(10) in pretty}') +" > "$g_tmpdir/json_mod.out" 2>&1 + ret=$? + msg "CHECK: json模块返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "decoded_match=True" "$g_tmpdir/json_mod.out" + + # @测试步骤: 测试 math 模块导入和数学函数 + # @预期结果: 数学函数计算结果正确 + python3 -c " +import math +print(f'pi={math.pi:.4f}') +print(f'e={math.e:.4f}') +print(f'sqrt_16={math.sqrt(16)}') +print(f'ceil_3.2={math.ceil(3.2)}') +print(f'floor_3.8={math.floor(3.8)}') +print(f'factorial_5={math.factorial(5)}') +print(f'gcd_12_8={math.gcd(12, 8)}') +" > "$g_tmpdir/math_mod.out" 2>&1 + ret=$? + msg "CHECK: math模块返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "pi=3.1416" "$g_tmpdir/math_mod.out" + assert_true grep -q "sqrt_16=4.0" "$g_tmpdir/math_mod.out" + assert_true grep -q "factorial_5=120" "$g_tmpdir/math_mod.out" + + # @测试步骤: 测试 datetime 模块导入和日期时间操作 + # @预期结果: 日期时间获取和计算正确 + python3 -c " +import datetime +now = datetime.datetime.now() +print(f'year={now.year}') +print(f'has_date={hasattr(now, \"year\")}') +delta = datetime.timedelta(days=1, hours=2, minutes=3) +print(f'total_seconds={delta.total_seconds()}') +today = datetime.date.today() +print(f'today_type={type(today).__name__}') +" > "$g_tmpdir/datetime_mod.out" 2>&1 + ret=$? + msg "CHECK: datetime模块返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "total_seconds=93780.0" "$g_tmpdir/datetime_mod.out" + + # @测试步骤: 测试 collections 模块导入和数据结构 + # @预期结果: 高级数据结构功能正确 + python3 -c " +from collections import Counter, defaultdict, namedtuple +c = Counter(['a', 'b', 'a', 'c', 'a', 'b']) +print(f'most_common={c.most_common(1)}') +dd = defaultdict(int) +dd['x'] += 1 +print(f'defaultdict={dict(dd)}') +Point = namedtuple('Point', ['x', 'y']) +p = Point(1, 2) +print(f'namedtuple={p.x},{p.y}') +" > "$g_tmpdir/collections_mod.out" 2>&1 + ret=$? + msg "CHECK: collections模块返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "defaultdict=" "$g_tmpdir/collections_mod.out" + assert_true grep -q "namedtuple=1,2" "$g_tmpdir/collections_mod.out" + + # @测试步骤: 测试 re 模块导入和正则表达式 + # @预期结果: 正则表达式匹配、搜索和替换功能正确 + python3 -c " +import re +text = 'hello world 123' +print(f'search={bool(re.search(\"world\", text))}') +print(f'match={bool(re.match(\"hello\", text))}') +digit_pat = r'\d+' +print(f'findall={re.findall(digit_pat, text)}') +print(f'sub={re.sub(\"world\", \"Python\", text)}') +space_pat = r'\s+' +print(f'split={re.split(space_pat, text)}') +" > "$g_tmpdir/re_mod.out" 2>&1 + ret=$? + msg "CHECK: re模块返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "search=True" "$g_tmpdir/re_mod.out" + assert_true grep -q "findall=" "$g_tmpdir/re_mod.out" + assert_true grep -q "sub=hello Python 123" "$g_tmpdir/re_mod.out" + + # @测试步骤: 测试 hashlib 模块导入和哈希计算 + # @预期结果: MD5 和 SHA256 哈希计算正确 + python3 -c " +import hashlib +md5 = hashlib.md5(b'hello').hexdigest() +sha256 = hashlib.sha256(b'hello').hexdigest() +print(f'md5_len={len(md5)}') +print(f'sha256_len={len(sha256)}') +print(f'md5_known={md5 == \"5d41402abc4b2a76b9719d911017c592\"}') +print(f'sha256_starts={sha256[:8]}') +" > "$g_tmpdir/hashlib_mod.out" 2>&1 + ret=$? + msg "CHECK: hashlib模块返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "md5_len=32" "$g_tmpdir/hashlib_mod.out" + assert_true grep -q "sha256_len=64" "$g_tmpdir/hashlib_mod.out" + assert_true grep -q "md5_known=True" "$g_tmpdir/hashlib_mod.out" + + # @测试步骤: 测试 random 模块导入和随机数生成 + # @预期结果: 随机数生成和选择功能正常 + python3 -c " +import random +random.seed(42) +r = random.randint(1, 100) +print(f'randint_in_range={1 <= r <= 100}') +choice = random.choice(['a', 'b', 'c']) +print(f'choice_valid={choice in [\"a\", \"b\", \"c\"]}') +random.seed(42) +r2 = random.randint(1, 100) +print(f'seeded_reproducible={r == r2}') +sample = random.sample(range(10), 3) +print(f'sample_len={len(sample)}') +" > "$g_tmpdir/random_mod.out" 2>&1 + ret=$? + msg "CHECK: random模块返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "randint_in_range=True" "$g_tmpdir/random_mod.out" + assert_true grep -q "seeded_reproducible=True" "$g_tmpdir/random_mod.out" + assert_true grep -q "sample_len=3" "$g_tmpdir/random_mod.out" + + # @测试步骤: 测试 pathlib 模块导入和路径操作 + # @预期结果: 路径操作功能正确 + python3 -c " +from pathlib import Path +p = Path('/usr/bin/python3.11') +print(f'name={p.name}') +print(f'suffix={p.suffix}') +print(f'parent={p.parent}') +print(f'is_absolute={p.is_absolute()}') +print(f'exists={p.exists()}') +joined = Path('/tmp') / 'test' / 'file.txt' +print(f'joined={joined}') +" > "$g_tmpdir/pathlib_mod.out" 2>&1 + ret=$? + msg "CHECK: pathlib模块返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "name=python3.11" "$g_tmpdir/pathlib_mod.out" + assert_true grep -q "suffix=.11" "$g_tmpdir/pathlib_mod.out" + assert_true grep -q "is_absolute=True" "$g_tmpdir/pathlib_mod.out" + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-interpreter-version.sh b/python3/testcase/python3-interpreter-version.sh new file mode 100755 index 0000000000000000000000000000000000000000..50ffb82effd4e85b90ca4e4e0ae4c547e19ebcba --- /dev/null +++ b/python3/testcase/python3-interpreter-version.sh @@ -0,0 +1,91 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180844-147028929 +# @用例名称: python3-interpreter-version +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 解释器的版本信息输出、--version 和 -V 选项功能正常 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 执行 python3 --version 查看版本信息 + # @预期结果: 输出包含 Python 版本字符串,返回码为 0 + python3 --version > "$g_tmpdir/version.out" 2>&1 + ret=$? + msg "CHECK: python3 --version 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + msg "CHECK: 版本输出内容, 实际值=$(cat "$g_tmpdir/version.out")" + assert_true grep -q "Python" "$g_tmpdir/version.out" + + # @测试步骤: 执行 python3 -V 查看版本信息(短选项) + # @预期结果: 输出包含 Python 版本字符串,返回码为 0 + python3 -V > "$g_tmpdir/V.out" 2>&1 + ret=$? + msg "CHECK: python3 -V 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "Python" "$g_tmpdir/V.out" + + # @测试步骤: 执行 python3 -c "import sys; print(sys.version)" 获取详细版本 + # @预期结果: 输出包含版本号、构建日期和平台信息 + python3 -c "import sys; print(sys.version)" > "$g_tmpdir/sysver.out" 2>&1 + ret=$? + msg "CHECK: sys.version 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "OpenCloudOS\|GCC\|Linux" "$g_tmpdir/sysver.out" + + # @测试步骤: 执行 python3 -c "import sys; print(sys.executable)" 获取解释器路径 + # @预期结果: 输出 python3 可执行文件的绝对路径 + python3 -c "import sys; print(sys.executable)" > "$g_tmpdir/exe.out" 2>&1 + ret=$? + msg "CHECK: sys.executable 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "/python3" "$g_tmpdir/exe.out" + + # @测试步骤: 执行 python3 -c "import sys; print(sys.platform)" 获取平台信息 + # @预期结果: 输出为 linux + python3 -c "import sys; print(sys.platform)" > "$g_tmpdir/platform.out" 2>&1 + ret=$? + msg "CHECK: sys.platform 返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "linux" "$g_tmpdir/platform.out" + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-json-tool.sh b/python3/testcase/python3-json-tool.sh new file mode 100755 index 0000000000000000000000000000000000000000..4939b295edcf9c1bdc8ffdfe831075fd297d1a4c --- /dev/null +++ b/python3/testcase/python3-json-tool.sh @@ -0,0 +1,146 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-744495414 +# @用例名称: python3-json-tool +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 -m json.tool 模块的 JSON 格式化和验证功能,包括格式化输出、排序键、错误检测和文件输入 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" +g_valid_json="$g_tmpdir/valid.json" +g_compact_json="$g_tmpdir/compact.json" +g_invalid_json="$g_tmpdir/invalid.json" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + # @预置条件: 创建有效的 JSON 测试文件 + cat > "$g_valid_json" <<'JSONEOF' +{ + "name": "OpenCloudOS", + "version": 12, + "features": ["python3", "docker", "kubernetes"], + "config": { + "debug": false, + "port": 8080 + } +} +JSONEOF + + # @预置条件: 创建紧凑格式的 JSON 文件 + echo '{"z":3,"a":1,"m":2}' > "$g_compact_json" + + # @预置条件: 创建无效的 JSON 文件 + echo '{"key": "value",}' > "$g_invalid_json" + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 使用 json.tool 格式化有效的 JSON 文件 + # @预期结果: JSON 被正确格式化,包含缩进和换行 + python3 -m json.tool "$g_valid_json" > "$g_tmpdir/formatted.out" 2>&1 + ret=$? + msg "CHECK: json.tool格式化返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "OpenCloudOS" "$g_tmpdir/formatted.out" + assert_true grep -q "python3" "$g_tmpdir/formatted.out" + assert_true grep -q "8080" "$g_tmpdir/formatted.out" + + # @测试步骤: 使用 json.tool 通过 stdin 输入 JSON 并格式化 + # @预期结果: 从标准输入读取的 JSON 被正确格式化 + echo '{"hello": "world", "num": 42}' | python3 -m json.tool > "$g_tmpdir/stdin.out" 2>&1 + ret=$? + msg "CHECK: json.tool stdin返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "hello" "$g_tmpdir/stdin.out" + assert_true grep -q "42" "$g_tmpdir/stdin.out" + + # @测试步骤: 使用 json.tool 排序 JSON 键(sort_keys) + # @预期结果: JSON 键按字母顺序排列 + python3 -c " +import json, sys +with open('$g_compact_json') as f: + data = json.load(f) +print(json.dumps(data, sort_keys=True, indent=2)) +" > "$g_tmpdir/sorted.out" 2>&1 + ret=$? + msg "CHECK: json排序键返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + # 验证 'a' 在 'm' 之前,'m' 在 'z' 之前 + a_line=$(grep -n '"a"' "$g_tmpdir/sorted.out" | head -1 | cut -d: -f1) + m_line=$(grep -n '"m"' "$g_tmpdir/sorted.out" | head -1 | cut -d: -f1) + z_line=$(grep -n '"z"' "$g_tmpdir/sorted.out" | head -1 | cut -d: -f1) + msg "CHECK: 键排序位置 a=$a_line m=$m_line z=$z_line" + assert_true [ "$a_line" -lt "$m_line" ] + assert_true [ "$m_line" -lt "$z_line" ] + + # @测试步骤: 使用 json.tool 验证无效的 JSON 文件 + # @预期结果: 对无效 JSON 报错,返回非零退出码 + python3 -m json.tool "$g_invalid_json" > "$g_tmpdir/invalid.out" 2>&1 + ret=$? + msg "CHECK: json.tool无效JSON返回码, 实际值=$ret" + assert_false [ $ret -eq 0 ] + + # @测试步骤: 使用 json.tool 格式化嵌套 JSON 结构 + # @预期结果: 深层嵌套的 JSON 被正确格式化 + python3 -c " +import json +nested = {'level1': {'level2': {'level3': {'value': 'deep'}}}} +print(json.dumps(nested, indent=4)) +" > "$g_tmpdir/nested.out" 2>&1 + ret=$? + msg "CHECK: json嵌套格式化返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "level1" "$g_tmpdir/nested.out" + assert_true grep -q "deep" "$g_tmpdir/nested.out" + + # @测试步骤: 使用 json.tool 处理包含特殊字符的 JSON + # @预期结果: 包含 Unicode 和转义字符的 JSON 被正确处理 + python3 -c " +import json +data = {'unicode': '你好世界', 'escape': 'line1\nline2\ttab', 'emoji': '🎉'} +encoded = json.dumps(data, ensure_ascii=False, indent=2) +print(encoded) +decoded = json.loads(encoded) +print(f'match={data == decoded}') +" > "$g_tmpdir/special.out" 2>&1 + ret=$? + msg "CHECK: json特殊字符返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "你好世界" "$g_tmpdir/special.out" + assert_true grep -q "match=True" "$g_tmpdir/special.out" + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-pip-install.sh b/python3/testcase/python3-pip-install.sh new file mode 100755 index 0000000000000000000000000000000000000000..a8d0bee36d3171d97117930a1489f3a749dcca1e --- /dev/null +++ b/python3/testcase/python3-pip-install.sh @@ -0,0 +1,113 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-770637730 +# @用例名称: python3-pip-install +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 -m pip 的包管理功能,包括 pip 版本检查、包安装、包列表、包搜索和包卸载 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" +g_venv="$g_tmpdir/piptestvenv" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + # @预置条件: 创建虚拟环境用于测试 pip(venv 自带 pip) + python3 -m venv "$g_venv" > /dev/null 2>&1 + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 检查 pip 版本信息 + # @预期结果: pip 版本信息正常输出 + "$g_venv/bin/python3" -m pip --version > "$g_tmpdir/pip_ver.out" 2>&1 + ret=$? + msg "CHECK: pip版本返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "pip" "$g_tmpdir/pip_ver.out" + + # @测试步骤: 使用 pip 安装包(使用 --target 指定目录,避免影响系统) + # @预期结果: 包成功安装到指定目录 + mkdir -p "$g_tmpdir/pkgs" + "$g_venv/bin/python3" -m pip install --target "$g_tmpdir/pkgs" six > "$g_tmpdir/pip_install.out" 2>&1 + ret=$? + msg "CHECK: pip安装返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true test -f "$g_tmpdir/pkgs/six.py" + + # @测试步骤: 使用 pip list 列出已安装的包 + # @预期结果: 列出已安装的包信息 + "$g_venv/bin/python3" -m pip list > "$g_tmpdir/pip_list.out" 2>&1 + ret=$? + msg "CHECK: pip list返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "pip" "$g_tmpdir/pip_list.out" + + # @测试步骤: 使用 pip show 查看包详情 + # @预期结果: 显示包的详细信息 + "$g_venv/bin/python3" -m pip show pip > "$g_tmpdir/pip_show.out" 2>&1 + ret=$? + msg "CHECK: pip show返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "Name: pip" "$g_tmpdir/pip_show.out" + + # @测试步骤: 使用 pip install 安装指定版本的包 + # @预期结果: 指定版本的包安装成功 + mkdir -p "$g_tmpdir/pkgs2" + "$g_venv/bin/python3" -m pip install --target "$g_tmpdir/pkgs2" "six>=1.0.0" > "$g_tmpdir/pip_ver_install.out" 2>&1 + ret=$? + msg "CHECK: pip指定版本安装返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + + # @测试步骤: 使用 pip 在虚拟环境中安装包并验证可导入 + # @预期结果: 安装的包可以在虚拟环境中导入使用 + "$g_venv/bin/python3" -m pip install --target "$g_tmpdir/pkgs" requests > "$g_tmpdir/pip_requests.out" 2>&1 + ret=$? + msg "CHECK: pip安装requests返回码, 实际值=$ret" + # 不强制要求 requests 安装成功(可能网络问题),但 pip 命令本身应正常 + if [ $ret -eq 0 ]; then + "$g_venv/bin/python3" -c "import sys; sys.path.insert(0, '$g_tmpdir/pkgs'); import requests; print(f'requests_ok=True')" > "$g_tmpdir/import_req.out" 2>&1 + assert_true grep -q "requests_ok=True" "$g_tmpdir/import_req.out" + fi + + # @测试步骤: 使用 pip check 检查依赖兼容性 + # @预期结果: 依赖检查命令正常执行 + "$g_venv/bin/python3" -m pip check > "$g_tmpdir/pip_check.out" 2>&1 + ret=$? + msg "CHECK: pip check返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-py-compile.sh b/python3/testcase/python3-py-compile.sh new file mode 100755 index 0000000000000000000000000000000000000000..40269980d8985853337c4e1457871b517fb41a01 --- /dev/null +++ b/python3/testcase/python3-py-compile.sh @@ -0,0 +1,143 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-717491946 +# @用例名称: python3-py-compile +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 -m py_compile 和 compileall 模块的字节码编译功能,包括单文件编译、批量编译和编译输出验证 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" +g_testpy="$g_tmpdir/hello.py" +g_moddir="$g_tmpdir/mymodule" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + # @预置条件: 创建测试 Python 文件 + cat > "$g_testpy" <<'PYEOF' +def greet(name): + return f"Hello, {name}!" + +if __name__ == "__main__": + print(greet("World")) +PYEOF + + # @预置条件: 创建模块目录和 __init__.py + mkdir -p "$g_moddir" + cat > "$g_moddir/__init__.py" <<'PYEOF' +"""My module.""" +from .utils import helper +PYEOF + cat > "$g_moddir/utils.py" <<'PYEOF' +"""Utility functions.""" +def helper(): + return "helper result" +PYEOF + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 使用 py_compile 编译单个 Python 文件 + # @预期结果: 编译成功,生成 __pycache__ 目录和 .pyc 文件 + python3 -m py_compile "$g_testpy" > "$g_tmpdir/compile1.out" 2>&1 + ret=$? + msg "CHECK: py_compile单文件返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true test -d "$g_tmpdir/__pycache__" + # 查找生成的 .pyc 文件 + pyc_count=$(find "$g_tmpdir/__pycache__" -name "hello.*.pyc" 2>/dev/null | wc -l) + msg "CHECK: 生成的pyc文件数量, 实际值=$pyc_count" + assert_true [ "$pyc_count" -ge 1 ] + + # @测试步骤: 使用 py_compile 编译并指定输出文件 + # @预期结果: 编译成功,生成的 .pyc 文件存在 + python3 -c " +import py_compile +import os +import glob +py_compile.compile('$g_testpy', doraise=True) +pyc_files = glob.glob('$g_tmpdir/__pycache__/hello.*.pyc') +assert len(pyc_files) >= 1, 'pyc file not found' +print('compile_ok=True') +" > "$g_tmpdir/compile2.out" 2>&1 + ret=$? + msg "CHECK: py_compile指定输出返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "compile_ok=True" "$g_tmpdir/compile2.out" + + # @测试步骤: 使用 compileall 批量编译目录中的 Python 文件 + # @预期结果: 目录中所有 .py 文件被编译 + python3 -m compileall "$g_moddir" > "$g_tmpdir/compileall.out" 2>&1 + ret=$? + msg "CHECK: compileall批量编译返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + # 检查是否生成了 __pycache__ 目录 + assert_true test -d "$g_moddir/__pycache__" + + # @测试步骤: 验证编译后的 .pyc 文件可以被 Python 加载执行 + # @预期结果: 从 .pyc 文件加载的模块功能正常 + python3 -c " +import importlib.util +import glob +pyc_files = glob.glob('$g_tmpdir/__pycache__/hello.*.pyc') +if pyc_files: + spec = importlib.util.spec_from_file_location('hello', pyc_files[0]) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + result = mod.greet('Test') + print(f'result={result}') + print(f'loaded=True') +else: + print('loaded=False') +" > "$g_tmpdir/load_pyc.out" 2>&1 + ret=$? + msg "CHECK: 加载pyc文件返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "loaded=True" "$g_tmpdir/load_pyc.out" + assert_true grep -q "result=Hello, Test!" "$g_tmpdir/load_pyc.out" + + # @测试步骤: 验证编译无效 Python 文件会报错 + # @预期结果: 编译语法错误的文件返回非零退出码 + cat > "$g_tmpdir/bad.py" <<'PYEOF' +def broken( + # syntax error: missing closing paren +PYEOF + python3 -m py_compile "$g_tmpdir/bad.py" > "$g_tmpdir/compile_bad.out" 2>&1 + ret=$? + msg "CHECK: 编译错误文件返回码, 实际值=$ret" + assert_false [ $ret -eq 0 ] + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-script-file-execution.sh b/python3/testcase/python3-script-file-execution.sh new file mode 100755 index 0000000000000000000000000000000000000000..ea3c91b65794652f699241e9597ec5ad7b9f1842 --- /dev/null +++ b/python3/testcase/python3-script-file-execution.sh @@ -0,0 +1,136 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-533047957 +# @用例名称: python3-script-file-execution +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 能够正确执行 .py 脚本文件,包括基本脚本执行、带参数脚本执行和脚本返回值处理 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" +g_script="$g_tmpdir/hello.py" +g_args_script="$g_tmpdir/args.py" +g_exit_script="$g_tmpdir/exit_code.py" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + # @预置条件: 创建基本测试脚本 + cat > "$g_script" <<'PYEOF' +#!/usr/bin/env python3 +"""Simple hello world script.""" +print("Hello from script file!") +name = "OpenCloudOS" +version = 12 +print(f"Platform: {name} Version: {version}") +PYEOF + + # @预置条件: 创建带参数测试脚本 + cat > "$g_args_script" <<'PYEOF' +#!/usr/bin/env python3 +"""Script that processes command line arguments.""" +import sys +args = sys.argv[1:] +print(f"Number of arguments: {len(args)}") +for i, arg in enumerate(args): + print(f"Arg {i}: {arg}") +PYEOF + + # @预置条件: 创建退出码测试脚本 + cat > "$g_exit_script" <<'PYEOF' +#!/usr/bin/env python3 +"""Script that returns specific exit code.""" +import sys +value = int(sys.argv[1]) if len(sys.argv) > 1 else 0 +if value > 0: + sys.exit(0) +else: + sys.exit(1) +PYEOF + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 执行基本 Python 脚本文件 + # @预期结果: 脚本正常执行,输出 Hello from script file! 和平台信息 + python3 "$g_script" > "$g_tmpdir/script.out" 2>&1 + ret=$? + msg "CHECK: 脚本执行返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "Hello from script file!" "$g_tmpdir/script.out" + assert_true grep -q "OpenCloudOS" "$g_tmpdir/script.out" + + # @测试步骤: 执行带命令行参数的脚本 + # @预期结果: 脚本正确接收并输出参数信息 + python3 "$g_args_script" foo bar baz > "$g_tmpdir/args.out" 2>&1 + ret=$? + msg "CHECK: 参数脚本返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "Number of arguments: 3" "$g_tmpdir/args.out" + assert_true grep -q "Arg 0: foo" "$g_tmpdir/args.out" + assert_true grep -q "Arg 2: baz" "$g_tmpdir/args.out" + + # @测试步骤: 执行返回退出码 0 的脚本 + # @预期结果: 脚本返回退出码 0 + python3 "$g_exit_script" 5 > /dev/null 2>&1 + ret=$? + msg "CHECK: 退出码0脚本返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + + # @测试步骤: 执行返回退出码 1 的脚本 + # @预期结果: 脚本返回退出码 1 + python3 "$g_exit_script" 0 > /dev/null 2>&1 + ret=$? + msg "CHECK: 退出码1脚本返回码, 实际值=$ret" + assert_true [ $ret -eq 1 ] + + # @测试步骤: 执行包含多行逻辑的脚本(含函数定义和调用) + # @预期结果: 脚本正确执行,输出计算结果 + cat > "$g_tmpdir/calc.py" <<'PYEOF' +def factorial(n): + if n <= 1: + return 1 + return n * factorial(n - 1) + +for i in range(1, 6): + print(f"{i}! = {factorial(i)}") +PYEOF + python3 "$g_tmpdir/calc.py" > "$g_tmpdir/calc.out" 2>&1 + ret=$? + msg "CHECK: 递归脚本返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "5! = 120" "$g_tmpdir/calc.out" + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-string-operations.sh b/python3/testcase/python3-string-operations.sh new file mode 100755 index 0000000000000000000000000000000000000000..ec0e0de5973de74513fe32e7032067b634708248 --- /dev/null +++ b/python3/testcase/python3-string-operations.sh @@ -0,0 +1,196 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-796650518 +# @用例名称: python3-string-operations +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 字符串操作的全面功能,包括格式化、切片、搜索、替换、分割、连接、大小写转换、填充和编码 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 测试 f-string 格式化 + # @预期结果: f-string 正确格式化变量和表达式 + python3 -c " +name = 'Python' +version = 3.11 +print(f'greeting=Hello, {name}!') +print(f'version={version:.1f}') +print(f'calc={2 + 3}') +print(f'repr={repr(name)}') +" > "$g_tmpdir/fstring.out" 2>&1 + ret=$? + msg "CHECK: f-string返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "greeting=Hello, Python!" "$g_tmpdir/fstring.out" + assert_true grep -q "version=3.1" "$g_tmpdir/fstring.out" + assert_true grep -q "calc=5" "$g_tmpdir/fstring.out" + + # @测试步骤: 测试字符串切片和索引 + # @预期结果: 切片操作正确返回子串 + python3 -c " +s = 'OpenCloudOS' +print(f'first={s[0]}') +print(f'last={s[-1]}') +print(f'slice_0_4={s[0:4]}') +print(f'slice_neg={s[-3:]}') +print(f'step2={s[::2]}') +print(f'reverse={s[::-1]}') +" > "$g_tmpdir/slice.out" 2>&1 + ret=$? + msg "CHECK: 字符串切片返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "first=O" "$g_tmpdir/slice.out" + assert_true grep -q "slice_0_4=Open" "$g_tmpdir/slice.out" + assert_true grep -q "reverse=SOduolCnepO" "$g_tmpdir/slice.out" + + # @测试步骤: 测试字符串搜索方法(find、index、startswith、endswith、in) + # @预期结果: 搜索方法正确返回位置或布尔值 + python3 -c " +s = 'hello world' +print(f'find_world={s.find(\"world\")}') +print(f'find_missing={s.find(\"xyz\")}') +print(f'startswith={s.startswith(\"hello\")}') +print(f'endswith={s.endswith(\"world\")}') +print(f'contains={\"world\" in s}') +print(f'count_l={s.count(\"l\")}') +" > "$g_tmpdir/search.out" 2>&1 + ret=$? + msg "CHECK: 字符串搜索返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "find_world=6" "$g_tmpdir/search.out" + assert_true grep -q "find_missing=-1" "$g_tmpdir/search.out" + assert_true grep -q "startswith=True" "$g_tmpdir/search.out" + assert_true grep -q "count_l=3" "$g_tmpdir/search.out" + + # @测试步骤: 测试字符串替换方法 + # @预期结果: 替换操作正确执行 + python3 -c " +s = 'hello world hello' +print(f'replace={s.replace(\"hello\", \"hi\")}') +print(f'replace_once={s.replace(\"hello\", \"hi\", 1)}') +print(f'translate={s.translate(str.maketrans(\"o\", \"0\"))}') +" > "$g_tmpdir/replace.out" 2>&1 + ret=$? + msg "CHECK: 字符串替换返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "replace=hi world hi" "$g_tmpdir/replace.out" + assert_true grep -q "replace_once=hi world hello" "$g_tmpdir/replace.out" + + # @测试步骤: 测试字符串分割和连接 + # @预期结果: 分割和连接操作正确 + python3 -c " +s = 'apple,banana,cherry' +parts = s.split(',') +print(f'split={parts}') +print(f'split_max={s.split(\",\", 1)}') +lines = 'line1\nline2\nline3' +print(f'splitlines={lines.splitlines()}') +joined = '-'.join(['a', 'b', 'c']) +print(f'join={joined}') +csv = ','.join(['x', 'y', 'z']) +print(f'csv={csv}') +" > "$g_tmpdir/split_join.out" 2>&1 + ret=$? + msg "CHECK: 分割连接返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "join=a-b-c" "$g_tmpdir/split_join.out" + assert_true grep -q "csv=x,y,z" "$g_tmpdir/split_join.out" + + # @测试步骤: 测试字符串大小写转换 + # @预期结果: 大小写转换正确 + python3 -c " +s = 'Hello World' +print(f'upper={s.upper()}') +print(f'lower={s.lower()}') +print(f'title={s.title()}') +print(f'capitalize={s.capitalize()}') +print(f'swapcase={s.swapcase()}') +print(f'is_upper={\"HELLO\".isupper()}') +print(f'is_lower={\"hello\".islower()}') +" > "$g_tmpdir/case.out" 2>&1 + ret=$? + msg "CHECK: 大小写转换返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "upper=HELLO WORLD" "$g_tmpdir/case.out" + assert_true grep -q "title=Hello World" "$g_tmpdir/case.out" + assert_true grep -q "swapcase=hELLO wORLD" "$g_tmpdir/case.out" + + # @测试步骤: 测试字符串填充和对齐(ljust、rjust、center、zfill) + # @预期结果: 填充和对齐操作正确 + python3 -c " +s = '42' +print(f'ljust={s.ljust(5, \"*\")}') +print(f'rjust={s.rjust(5, \"*\")}') +print(f'center={s.center(6, \"-\")}') +print(f'zfill={s.zfill(5)}') +print(f'strip={\" hello \".strip()}') +print(f'lstrip={\" hello \".lstrip()}') +print(f'rstrip={\" hello \".rstrip()}') +" > "$g_tmpdir/pad.out" 2>&1 + ret=$? + msg "CHECK: 填充对齐返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "ljust=42" "$g_tmpdir/pad.out" + assert_true grep -q "rjust=" "$g_tmpdir/pad.out" + assert_true grep -q "zfill=00042" "$g_tmpdir/pad.out" + assert_true grep -q "strip=hello" "$g_tmpdir/pad.out" + + # @测试步骤: 测试字符串编码和解码 + # @预期结果: UTF-8 编码和解码正确 + python3 -c " +s = '你好 Python3' +encoded = s.encode('utf-8') +decoded = encoded.decode('utf-8') +print(f'encoded_len={len(encoded)}') +print(f'decoded={decoded}') +print(f'match={s == decoded}') +ascii_s = 'Hello' +ascii_enc = ascii_s.encode('ascii') +print(f'ascii_len={len(ascii_enc)}') +" > "$g_tmpdir/encode.out" 2>&1 + ret=$? + msg "CHECK: 编码解码返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "decoded=你好 Python3" "$g_tmpdir/encode.out" + assert_true grep -q "match=True" "$g_tmpdir/encode.out" + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +############################################################################### diff --git a/python3/testcase/python3-venv-create.sh b/python3/testcase/python3-venv-create.sh new file mode 100755 index 0000000000000000000000000000000000000000..724bf6a865aa70139db8db041f4137606596ef01 --- /dev/null +++ b/python3/testcase/python3-venv-create.sh @@ -0,0 +1,102 @@ +#!/bin/bash +############################################################################### +# @用例ID: 20260425-180853-691245673 +# @用例名称: python3-venv-create +# @用例级别: 3 +# @用例标签: python3 +# @扩展属性: +# @用例类型: 功能测试 +# @自动化: 1 +# @超时时间: 0 +# @用例描述: 验证 python3 -m venv 创建和管理虚拟环境的功能,包括创建虚拟环境、验证目录结构、激活脚本和独立 Python 解释器 +############################################################################### +if [ -z "$TST_TS_TOPDIR" ]; then + TST_TS_TOPDIR="$(realpath "$(dirname "$0")/..")" + while [ "$TST_TS_TOPDIR" != "/" ]; do + [ -f "${TST_TS_TOPDIR}/tsuite" ] && break + TST_TS_TOPDIR="$(dirname "$TST_TS_TOPDIR")" + done + export TST_TS_TOPDIR +fi +source "${TST_TS_TOPDIR}/common/lib/common.sh" || exit 1 +############################################################################### + +g_tmpdir="$(mktemp -d)" +g_venv="$g_tmpdir/testvenv" + +tc_setup() { + msg "this is tc_setup" + + # @预置条件: 安装 python3 软件包 + msg "CHECK: 安装 python3 软件包的命令即将执行" + assert_true which python3 + + return 0 +} + +do_test() { + msg "this is do_test" + + # @测试步骤: 使用 python3 -m venv 创建虚拟环境 + # @预期结果: 虚拟环境创建成功,返回码为 0 + python3 -m venv "$g_venv" > "$g_tmpdir/venv_create.out" 2>&1 + ret=$? + msg "CHECK: venv创建返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + + # @测试步骤: 验证虚拟环境的目录结构 + # @预期结果: 包含 bin、lib 等标准目录 + assert_true test -d "$g_venv/bin" + assert_true test -d "$g_venv/lib" + assert_true test -f "$g_venv/pyvenv.cfg" + msg "CHECK: 虚拟环境目录结构验证通过" + + # @测试步骤: 验证虚拟环境中的 Python 解释器 + # @预期结果: 虚拟环境中有独立的 Python 可执行文件 + assert_true test -x "$g_venv/bin/python3" + "$g_venv/bin/python3" --version > "$g_tmpdir/venv_python.out" 2>&1 + ret=$? + msg "CHECK: venv Python版本返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "Python" "$g_tmpdir/venv_python.out" + + # @测试步骤: 验证虚拟环境的激活脚本 + # @预期结果: activate 脚本存在且可执行 + assert_true test -f "$g_venv/bin/activate" + msg "CHECK: activate脚本存在" + + # @测试步骤: 验证虚拟环境的 pyvenv.cfg 配置文件 + # @预期结果: 配置文件包含 home 和 version 信息 + assert_true grep -q "home" "$g_venv/pyvenv.cfg" + assert_true grep -q "version" "$g_venv/pyvenv.cfg" + msg "CHECK: pyvenv.cfg配置验证通过" + + # @测试步骤: 使用虚拟环境中的 Python 执行代码 + # @预期结果: 虚拟环境的 Python 能正常执行代码 + "$g_venv/bin/python3" -c "import sys; print(sys.prefix); print(sys.executable)" > "$g_tmpdir/venv_exec.out" 2>&1 + ret=$? + msg "CHECK: venv Python执行返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true grep -q "testvenv" "$g_tmpdir/venv_exec.out" + + # @测试步骤: 使用 --without-pip 创建不带 pip 的虚拟环境 + # @预期结果: 虚拟环境创建成功,但不包含 pip + python3 -m venv --without-pip "$g_tmpdir/venv_nopip" > "$g_tmpdir/venv_nopip.out" 2>&1 + ret=$? + msg "CHECK: venv无pip创建返回码, 实际值=$ret" + assert_true [ $ret -eq 0 ] + assert_true test -d "$g_tmpdir/venv_nopip/bin" + assert_true test -x "$g_tmpdir/venv_nopip/bin/python3" + + return 0 +} + +tc_teardown() { + msg "this is tc_teardown" + rm -rfv "$g_tmpdir" || return 1 + return 0 +} + +############################################################################### +tst_main "$@" +###############################################################################