首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >致测试/开发同学:别再手动创建Python文件了!这份自动化攻略请收好

致测试/开发同学:别再手动创建Python文件了!这份自动化攻略请收好

作者头像
大飞记Python
发布2026-04-14 20:39:57
发布2026-04-14 20:39:57
340
举报

作为开发人员,我们平时编写代码之前,通常是这样的流程:

在 conf 文件夹下,为 xxx 创建一个子文件夹,并在这个子文件夹里创建 xxx.py 文件 在 data 文件夹下,为 xxx 创建一个子文件夹,并在这个子文件夹里创建 xxx.json 文件 在 page 文件夹下,为 xxx 创建一个子文件夹,并在这个子文件夹里创建 xxx.py 文件 在 scripts 文件夹下,为 xxx 创建一个子文件夹,并在这个子文件夹里创建 test_xxx.py 文件

一顿操作猛如虎,一看战绩零杠五!光新建文件夹就花了10分钟,然后就已经累了😂

尤其很多企业级项目使用了PO模型框架,它的框架清晰,结构完整,可以适用于绝大多数的大型企业的项目;但同时也存在新建项目文件麻烦,维护成本略高等缺陷

需求

这也太不自动化了!我们希望:

  • 自动创建完整结构:一键创建 conf、data、page、scripts 四个目录中的对应文件夹和文件
  • 灵活性高:当我输入xxx时,新建对应的文件及文件夹
  • 输入验证:确保文件名称只包含英文字母、数字和下划线;如果名称已存在,可以选择覆盖、新建、取消等操作
  • 语言:最好使用Python语言进行编写,方便阅读和后续维护
  • 交互模式:提供友好且简单的交互式界面

既然需求已经明确,那么‘简单’的编码环节就开始了~😏

使用教程

先说一下如何使用脚本吧,源码放在文章最后。当然老规矩,后台回复“批量创建”也可以获得项目的完整源码

存放位置

需要将这两个代码放在我们的项目根目录下,以确保脚本可以正常运行

代码介绍

分为 auto_create.py 和 interactive_creator.py 两个脚本

  • auto_create.py:主运行脚本
  • interactive_creator.py:可交互命令行脚本,平时右击运行即可

使用

右击运行 interactive_creator.py

image-20251112上午111727576
image-20251112上午111727576

输入想创建的文件名称,比如gongzhonghao

若文件名称符合命名规范且不存在,则创建成功

iShot_2025-11-12_上午10.19.11
iShot_2025-11-12_上午10.19.11

查看项目目录,创建成功

iShot_2025-11-12_上午10.20.58
iShot_2025-11-12_上午10.20.58

若文件名称不规范(比如出现中文),提示错误

iShot_2025-11-12_上午10.23.25
iShot_2025-11-12_上午10.23.25

若文件名已存在,则询问覆盖、新建、取消

这么做是为了最大程度地保护我们代码的安全。如果没有文件名是否存在的校验,直接进行新建操作,会带来无法估量的代码损失

iShot_2025-11-12_上午10.33.10
iShot_2025-11-12_上午10.33.10

最后按照提示,继续新建or退出

iShot_2025-11-12_上午10.19.26
iShot_2025-11-12_上午10.19.26

注意:由于批量删除操作为非常敏感的操作,本脚本不提供任何的批量删除功能。也提醒小伙伴们尽可能少使用批量删除操作,以免造成无法估量的损失

代码源码

auto_create.py

代码语言:javascript
复制
import os
import argparse
import re
import shutil


def check_module_exists(module_name):
    """
    检查模块是否已经存在
    返回存在的目录列表
    """
    base_dirs = ['conf', 'data', 'page', 'scripts']
    existing_dirs = []

    for dir_name in base_dirs:
        module_dir = os.path.join(dir_name, module_name)
        if os.path.exists(module_dir):
            existing_dirs.append(dir_name)

    return existing_dirs


def create_project_structure(module_name, force_overwrite=False):
    """
    根据模块名称创建标准的项目结构
    """
    # 验证输入是否为有效的英文或数字字符
    ifnot re.match(r'^[a-zA-Z0-9_]+$', module_name):
        print(f"错误: 模块名称 '{module_name}' 只能包含英文字母、数字和下划线")
        returnFalse

    # 检查模块是否已存在
    existing_dirs = check_module_exists(module_name)
    if existing_dirs andnot force_overwrite:
        print(f"⚠️  模块 '{module_name}' 在以下目录中已存在: {', '.join(existing_dirs)}")

        whileTrue:
            choice = input("请选择操作: (1)创建文件,但跳过已有文件 (2)删除并重新创建 (3)取消: ").strip()

            if choice == '1':
                # 覆盖模式 - 只创建不存在的部分,已存在的保留
                return create_with_overwrite(module_name, existing_dirs)
            elif choice == '2':
                # 删除并重新创建
                return recreate_module(module_name)
            elif choice == '3':
                print("❌ 操作已取消")
                returnFalse
            else:
                print("❌ 无效选择,请输入 1, 2 或 3")

    # 如果模块不存在或强制覆盖,直接创建
    return create_new_module(module_name)


def create_new_module(module_name):
    """创建新模块"""
    base_dirs = {
        'conf': f'{module_name}.py',
        'data': f'{module_name}.json',
        'page': f'{module_name}.py',
        'scripts': f'test_{module_name}.py'
    }

    created_items = []

    try:
        for dir_name, file_name in base_dirs.items():
            # 创建主文件夹
            main_dir_path = os.path.join(dir_name, module_name)
            os.makedirs(main_dir_path, exist_ok=True)

            # 创建对应的文件
            file_path = os.path.join(main_dir_path, file_name)
            with open(file_path, 'w', encoding='utf-8') as f:
                # 根据文件类型添加基本内容
                if file_name.endswith('.py'):
                    if dir_name == 'scripts':  # test文件
                        f.write(generate_test_template(module_name))
                    else:  # 普通py文件
                        f.write(generate_py_template(module_name, dir_name))
                elif file_name.endswith('.json'):
                    f.write(generate_json_template(module_name))

            created_items.append(f"  - {file_path}")

        print(f"✅ 成功创建模块 '{module_name}' 的完整结构:")
        for item in created_items:
            print(item)
        returnTrue

    except Exception as e:
        print(f"❌ 创建过程中出现错误: {e}")
        returnFalse


def create_with_overwrite(module_name, existing_dirs):
    """覆盖模式 - 只创建不存在的部分"""
    base_dirs = {
        'conf': f'{module_name}.py',
        'data': f'{module_name}.json',
        'page': f'{module_name}.py',
        'scripts': f'test_{module_name}.py'
    }

    created_items = []
    skipped_items = []

    try:
        for dir_name, file_name in base_dirs.items():
            main_dir_path = os.path.join(dir_name, module_name)
            file_path = os.path.join(main_dir_path, file_name)

            if dir_name in existing_dirs:
                skipped_items.append(f"  - {file_path} (已存在,跳过)")
                continue

            # 创建主文件夹
            os.makedirs(main_dir_path, exist_ok=True)

            # 创建对应的文件
            with open(file_path, 'w', encoding='utf-8') as f:
                if file_name.endswith('.py'):
                    if dir_name == 'scripts':
                        f.write(generate_test_template(module_name))
                    else:
                        f.write(generate_py_template(module_name, dir_name))
                elif file_name.endswith('.json'):
                    f.write(generate_json_template(module_name))

            created_items.append(f"  - {file_path}")

        print(f"✅ 成功创建模块 '{module_name}' 的新增部分:")
        for item in created_items:
            print(item)
        if skipped_items:
            print(f"📋 跳过的已存在部分:")
            for item in skipped_items:
                print(item)
        returnTrue

    except Exception as e:
        print(f"❌ 创建过程中出现错误: {e}")
        returnFalse


def recreate_module(module_name):
    """删除并重新创建模块"""
    base_dirs = ['conf', 'data', 'page', 'scripts']

    try:
        # 首先删除所有已存在的模块目录
        for dir_name in base_dirs:
            module_dir = os.path.join(dir_name, module_name)
            if os.path.exists(module_dir):
                shutil.rmtree(module_dir)
                print(f"🗑️  已删除: {module_dir}")

        # 然后重新创建
        return create_new_module(module_name)

    except Exception as e:
        print(f"❌ 删除和重新创建过程中出现错误: {e}")
        returnFalse


def generate_py_template(module_name, dir_type):
    """生成Python文件模板"""
    templates = {
        'conf': f'''\"\"\"
{module_name} 配置文件
\"\"\"

# 配置项定义
class {module_name.capitalize()}Config:
    \"\"\"{module_name} 配置类\"\"\"

    # 基础配置
    ENABLED = True
    TIMEOUT = 30

    # 自定义配置
    def __init__(self):
        pass

# 全局配置实例
config = {module_name.capitalize()}Config()
''',
        'page': f'''\"\"\"
{module_name} 页面对象
\"\"\"

class {module_name.capitalize()}Page:
    \"\"\"{module_name} 页面操作类\"\"\"

    def __init__(self, driver):
        self.driver = driver

    def open(self):
        \"\"\"打开页面\"\"\"
        pass

    def perform_action(self):
        \"\"\"执行操作\"\"\"
        pass

# 使用示例
if __name__ == \"__main__\":
    pass
'''
    }
    return templates.get(dir_type, f"# {module_name} {dir_type} file\n")


def generate_test_template(module_name):
    """生成测试文件模板"""
    returnf'''\"\"\"
测试模块: {module_name}
\"\"\"

import pytest
import sys
import os

# 添加项目根目录到路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

class Test{module_name.capitalize()}:
    \"\"\"{module_name} 测试类\"\"\"

    def setup_method(self):
        \"\"\"测试前置操作\"\"\"
        pass

    def teardown_method(self):
        \"\"\"测试后置操作\"\"\"
        pass

    def test_{module_name}_basic(self):
        \"\"\"测试 {module_name} 基础功能\"\"\"
        assert True

    def test_{module_name}_advanced(self):
        \"\"\"测试 {module_name} 高级功能\"\"\"
        assert True

if __name__ == \"__main__\":
    pytest.main([__file__, \"-v\"])
'''


def generate_json_template(module_name):
    """生成JSON文件模板"""
    returnf'''{{
    "{module_name}_config": {{
        "enabled": true,
        "timeout": 30,
        "description": "{module_name} 配置文件"
    }},
    "test_data": {{
        "case_1": {{
            "input": "sample_input",
            "expected": "sample_output"
        }}
    }}
}}
'''


def list_existing_modules():
    """列出已存在的模块"""
    base_dirs = ['conf', 'data', 'page', 'scripts']
    modules = {}

    for base_dir in base_dirs:
        if os.path.exists(base_dir):
            for item in os.listdir(base_dir):
                item_path = os.path.join(base_dir, item)
                if os.path.isdir(item_path):
                    if item notin modules:
                        modules[item] = []
                    modules[item].append(base_dir)

    if modules:
        print("\n📁 已存在的模块:")
        for module, dirs in sorted(modules.items()):
            print(f"  - {module} (存在于: {', '.join(dirs)})")
    else:
        print("\n📁 暂无已存在的模块")


def main():
    parser = argparse.ArgumentParser(description='自动化创建测试项目结构')
    parser.add_argument('module_name', nargs='?', help='模块名称(英文或数字字符)')
    parser.add_argument('--list', '-l', action='store_true', help='列出所有已存在的模块')
    parser.add_argument('--force', '-f', action='store_true', help='强制覆盖已存在的模块')

    args = parser.parse_args()

    if args.list:
        list_existing_modules()
        return

    if args.module_name:
        success = create_project_structure(args.module_name, args.force)
        if success:
            print(f"\n🎉 模块 '{args.module_name}' 处理完成!")
        else:
            print(f"\n💥 模块 '{args.module_name}' 处理失败!")
    else:
        # 如果没有提供模块名称,进入交互模式
        interactive_mode()


def interactive_mode():
    """交互式模式"""
    print("🚀 项目结构自动化创建工具")
    print("=" * 50)

    whileTrue:
        module_name = input("\n请输入模块名称(英文或数字,输入 'quit' 退出): ").strip()

        if module_name.lower() == 'quit':
            break

        ifnot module_name:
            print("❌ 模块名称不能为空")
            continue

        ifnot re.match(r'^[a-zA-Z0-9_]+$', module_name):
            print("❌ 模块名称只能包含英文字母、数字和下划线")
            continue

        # 调用创建函数
        success = create_project_structure(module_name)

        if success:
            print(f"\n✅ 模块 '{module_name}' 处理成功!")
        else:
            print(f"\n❌ 模块 '{module_name}' 处理失败!")

        continue_create = input("\n是否继续创建其他模块?(y/n): ").strip().lower()
        if continue_create != 'y':
            break


if __name__ == "__main__":
    main()

interactive_creator.py

代码语言:javascript
复制
# interactive_creator.py - 交互式创建脚本
import os
import re


def interactive_create():
    """交互式创建项目结构"""
    print("🚀 项目结构自动化创建工具")
    print("=" * 40)

    whileTrue:
        module_name = input("\n请输入模块名称(英文或数字,输入 'quit' 退出): ").strip()

        if module_name.lower() == 'quit':
            break

        ifnot module_name:
            print("❌ 模块名称不能为空")
            continue

        ifnot re.match(r'^[a-zA-Z0-9_]+$', module_name):
            print("❌ 模块名称只能包含英文字母、数字和下划线")
            continue

        # 调用创建函数
        success = create_project_structure(module_name)

        if success:
            print(f"\n✅ 模块 '{module_name}' 创建成功!")
        else:
            print(f"\n❌ 模块 '{module_name}' 创建失败!")

        continue_create = input("\n是否继续创建其他模块?(y/n): ").strip().lower()
        if continue_create != 'y':
            break


if __name__ == "__main__":
    # 确保有 create_project_structure 函数
    from auto_create import create_project_structure

    interactive_create()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-11-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大飞记Python 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求
  • 使用教程
    • 存放位置
    • 代码介绍
    • 使用
  • 代码源码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档