Python中如何将Flask markdown格式的API文档转换为API与测试信息的mini轮子
在写好格式要求的 markdown 文档的前提下可以省不少力气写这些 api 文档的固定部分,包括 method, url arguments, post/put data, response data 还有 test 等等.仅适用于前后端分离.
使用场景有点局限,希望不被喷得太惨....
Github->: DocTrans
效果:

Python中如何将Flask markdown格式的API文档转换为API与测试信息的mini轮子
1 回复
我理解你想做一个能把Flask的Markdown格式API文档转换成可执行测试的小工具。这个需求很实用,我来给你一个可以直接用的方案。
核心思路是解析Markdown中的API信息(URL、方法、参数),然后生成对应的测试代码。下面是一个完整的实现:
import re
import json
import requests
from typing import Dict, List, Optional
import markdown
from bs4 import BeautifulSoup
class FlaskMarkdownToTester:
def __init__(self, markdown_file: str):
self.markdown_file = markdown_file
self.apis = []
def parse_markdown(self):
"""解析Markdown文件,提取API信息"""
with open(self.markdown_file, 'r', encoding='utf-8') as f:
content = f.read()
# 将markdown转换为HTML便于解析
html = markdown.markdown(content)
soup = BeautifulSoup(html, 'html.parser')
# 查找所有标题(假设API以##开头)
for h2 in soup.find_all('h2'):
api_name = h2.get_text().strip()
api_info = {'name': api_name, 'method': 'GET', 'url': '', 'params': {}}
# 查找下一个段落或代码块
next_elem = h2.find_next_sibling()
while next_elem and next_elem.name != 'h2':
if next_elem.name == 'p':
text = next_elem.get_text()
# 提取URL和方法
if 'POST' in text or 'GET' in text or 'PUT' in text or 'DELETE' in text:
method_match = re.search(r'(GET|POST|PUT|DELETE|PATCH)', text)
if method_match:
api_info['method'] = method_match.group(1)
url_match = re.search(r'`(/api/[^`]+)`', text)
if url_match:
api_info['url'] = url_match.group(1)
elif next_elem.name == 'pre':
code = next_elem.get_text()
# 尝试解析JSON参数示例
if '{' in code and '}' in code:
try:
json_start = code.find('{')
json_end = code.rfind('}') + 1
json_str = code[json_start:json_end]
params = json.loads(json_str)
api_info['params'] = params
except:
pass
next_elem = next_elem.find_next_sibling()
if api_info['url']: # 只有找到URL的才加入
self.apis.append(api_info)
return self.apis
def generate_test_code(self, base_url: str = "http://localhost:5000") -> str:
"""生成测试代码"""
if not self.apis:
self.parse_markdown()
test_code = """import unittest
import requests
import json
class TestFlaskAPIs(unittest.TestCase):
def setUp(self):
self.base_url = "{}"
self.session = requests.Session()
# 如果需要认证,在这里添加
# self.session.headers.update({'Authorization': 'Bearer token'})
""".format(base_url)
for i, api in enumerate(self.apis):
test_name = f"test_{api['name'].lower().replace(' ', '_')}"
method = api['method'].lower()
url = api['url']
params = json.dumps(api['params'], ensure_ascii=False, indent=2)
test_method = f"""
def {test_name}(self):
\"\"\"测试 {api['name']}\"\"\"
url = self.base_url + "{url}"
response = self.session.{method}(
url,
json={params} if {bool(api['params'])} else None
)
print(f"{{api['method']}} {{url}} - 状态码: {{response.status_code}}")
self.assertEqual(response.status_code, 200)
# 这里可以添加更多的断言
# self.assertIn('key', response.json())
"""
test_code += test_method
test_code += """
if __name__ == '__main__':
unittest.main()
"""
return test_code
def save_test_file(self, filename: str = "test_apis.py", base_url: str = "http://localhost:5000"):
"""保存测试文件"""
test_code = self.generate_test_code(base_url)
with open(filename, 'w', encoding='utf-8') as f:
f.write(test_code)
print(f"测试文件已生成: {filename}")
# 使用示例
if __name__ == "__main__":
# 假设你的Markdown文档文件名为api_docs.md
converter = FlaskMarkdownToTester("api_docs.md")
# 解析Markdown
apis = converter.parse_markdown()
print(f"找到 {len(apis)} 个API")
for api in apis:
print(f"{api['method']} {api['url']} - {api['name']}")
# 生成测试文件
converter.save_test_file("test_generated.py", "http://localhost:5000")
这个工具的工作原理:
- 用BeautifulSoup解析Markdown转换的HTML
- 通过正则表达式提取API方法、URL和参数
- 生成完整的unittest测试用例
- 可以直接运行生成的测试文件
如果你的Markdown格式比较特殊,可能需要调整正则表达式。这个方案给你一个基础框架,你可以根据实际文档格式进行定制。
总结:用解析+代码生成的方式实现文档到测试的转换。

