hexo-blog-deploy/2022/03/11/python+behave+openpyxl管理测试用例/index.html

16 lines
38 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width"><meta name="theme-color" content="#222"><meta name="generator" content="Hexo 5.4.2"><link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png"><link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png"><link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png"><link rel="mask-icon" href="/images/logo.svg" color="#222"><link rel="stylesheet" href="/css/main.css"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha256-HtsXJanqjKTc8vVQjO4YMhiqFoXkfBsjBWcX91T1jr8=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css" integrity="sha256-Vzbj7sDDS/woiFS3uNKo8eIuni59rjyNGtXfstRzStA=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/themes/blue/pace-theme-minimal.css"><script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script><script class="next-config" data-name="main" type="application/json">{"hostname":"kiki.kim","root":"/","images":"/images","scheme":"Gemini","darkmode":false,"version":"8.15.1","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"flat"},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":false,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果:${query}","hits_time":"找到 ${hits} 个搜索结果(用时 ${time} 毫秒)","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script><meta name="description" content="测试用例文本化使用python+behave来维护测试用例"><meta property="og:type" content="article"><meta property="og:title" content="python+behave+openpyxl管理测试用例"><meta property="og:url" content="http://kiki.kim/2022/03/11/python+behave+openpyxl%E7%AE%A1%E7%90%86%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B/index.html"><meta property="og:site_name" content="随言碎语"><meta property="og:description" content="测试用例文本化使用python+behave来维护测试用例"><meta property="og:locale" content="zh_CN"><meta property="article:published_time" content="2022-03-11T08:29:30.000Z"><meta property="article:modified_time" content="2023-05-11T04:48:55.004Z"><meta property="article:author" content="小梦同学"><meta property="article:tag" content="python"><meta property="article:tag" content="behave"><meta property="article:tag" content="自动化测试"><meta property="article:tag" content="测试"><meta name="twitter:card" content="summary"><link rel="canonical" href="http://kiki.kim/2022/03/11/python+behave+openpyxl%E7%AE%A1%E7%90%86%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B/"><script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"http://kiki.kim/2022/03/11/python+behave+openpyxl%E7%AE%A1%E7%90%86%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B/","path":"2022/03/11/python+behave+openpyxl管理测试用例/","title":"python+behave+openpyxl管理测试用例"}</script><script class="next-config" data-name="calendar" type="application/json">""</script><title>python+behave+openpyxl管理测试用例 | 随言碎语</title><noscript><link rel="stylesheet" href="/css/noscript.css"></noscript><link rel="alternate" href="/atom.xml" title="随言碎语" type="application/atom+xml"><style>.darkmode--activated{--body-bg-color:#282828;--content-bg-color:#333;--card-bg-color:#555;--text-color:#ccc;--blockquote-color:#bbb;--link-color:#ccc;--link-hover-color:#eee;--brand-color:#ddd;--brand-hover-color:#ddd;--table-row-odd-bg-color:#282828;--table-row-hover-bg-color:#363636;--menu-item-bg-color:#555;--btn-default-bg:#222;--btn-default-color:#ccc;--btn-default-border-color:#555;--btn-default-hover-bg:#666;--btn-default-hover-color:#ccc;--btn-default-hover-border-color:#666;--highlight-background:#282b2e;--highlight-foreground:#a9b7c6;--highlight-gutter-background:#34393d;--highlight-gutter-foreground:#9ca9b6}.darkmode--activated img{opacity:.75}.darkmode--activated img:hover{opacity:.9}.darkmode--activated code{color:#69dbdc;background:0 0}button.darkmode-toggle{z-index:9999}.darkmode-ignore,img{display:flex!important}.beian img{display:inline-block!important}</style></head><body itemscope itemtype="http://schema.org/WebPage"><div class="headband"></div><main class="main"><div class="column"><header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container"><div class="site-nav-toggle"><div class="toggle" aria-label="切换导航栏" role="button"><span class="toggle-line"></span> <span class="toggle-line"></span> <span class="toggle-line"></span></div></div><div class="site-meta"><a href="/" class="brand" rel="start"><i class="logo-line"></i><p class="site-title">随言碎语</p><i class="logo-line"></i></a><p class="site-subtitle" itemprop="description">咕叽咕叽</p></div><div class="site-nav-right"><div class="toggle popup-trigger" aria-label="搜索" role="button"><i class="fa fa-search fa-fw fa-lg"></i></div></div></div><nav class="site-nav"><ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签<span class="badge">63</span></a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档<span class="badge">56</span></a></li><li class="menu-item menu-item-talk"><a href="/talk/" rel="section"><i class="fa fa-commenting fa-fw"></i>碎语湖</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a></li><li class="menu-item menu-item-search"><a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索</a></li></ul></nav><div class="search-pop-overlay"><div class="popup search-popup"><div class="search-header"><span class="search-icon"><i class="fa fa-search"></i></span><div class="search-input-container"><input autocomplete="off" autocapitalize="off" maxlength="80" placeholder="搜索..." spellcheck="false" type="search" class="search-input"></div><span class="popup-btn-close" role="button"><i class="fa fa-times-circle"></i></span></div><div class="search-result-container no-result"><div class="search-result-icon"><i class="fa fa-spinner fa-pulse fa-5x"></i></div></div></div></div><script type="text/javascript" src="/js/cursor/zjAdd.js"></script><div class="musicwyy2" style="top:200px;position:fixed;left:0;bottom:0;z-index:105;opacity:1;width:45px;height:45px;font-size:45px;font-family:'Long Cang'"><button type="button" style="top:200px;width:45px;height:45px;margin-top:10px;margin-bottom:10px;border-width:0;z-index:200;background:0 0;border-width:0;outline:0" onclick="musicChange()"><img src="/images/wy.svg"></button></div><div class="musicwyy1" style="position:fixed;top:200px;left:0;bottom:0;z-index:100;opacity:1;width:45px;height:45px;font-size:0"><div class="aplayer-miniswitcher" style="top:200px;height:110px;width:20px;display:inline-block;overflow:hidden"></div><div style="width:calc(100% - 30px);top:200px;height:110px;display:none" id="musicZJ"><div class="musicwyy1" style="position:fixed;top:200px;left:15px;bottom:0;z-index:100;opacity:1;width:300px;height:110px;font-size:0"><div class="aplayer-miniswitcher" style="top:200px;height:110px;width:20px;display:inline-block;overflow:hidden"></div><div style="width:calc(100% - 30px);top:200px;height:110px;display:inline-block" id="musicZJ"><iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width="330" height="450" src="//music.163.com/outchain/player?type=0&id=8009036598&auto=0&height=430"></iframe></div></div></div></div></header><aside class="sidebar"><div class="sidebar-inner sidebar-nav-active sidebar-toc-active"><ul class="sidebar-nav"><li class="sidebar-nav-toc">文章目录</li><li class="sidebar-nav-overview">站点概览</li></ul><div class="sidebar-panel-container"><div class="post-toc-wrap sidebar-panel"><div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E8%83%8C%E6%99%AF"><span class="nav-number">1.</span> <span class="nav-text">1.背景</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D"><span class="nav-number">2.</span> <span class="nav-text">2.项目介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-1-%E5%B0%86%E5%8E%9F%E6%9C%89%E7%9A%84excel%E8%BD%AC%E5%8C%96%E4%B8%BAfeature"><span class="nav-number">3.</span> <span class="nav-text">2.1 将原有的excel转化为feature</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-2-%E5%B0%86feature%E8%BD%AC%E6%8D%A2%E4%B8%BAexcel"><span class="nav-number">4.</span> <span class="nav-text">2.2 将feature转换为excel</span></a></li></ol></div></div><div class="site-overview-wrap sidebar-panel"><div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person"><img class="site-author-image" itemprop="image" alt="小梦同学" src="https://halliday.oss-cn-nanjing.aliyuncs.com/imagesbjx.png"><p class="site-author-name" itemprop="name">小梦同学</p><div class="site-description" itemprop="description">欲买桂花同载酒,终不似,少年游。</div></div><div class="site-state-wrap animated"><nav class="site-state"><div class="site-state-item site-state-posts"><a href="/archives/"><span class="site-state-item-count">56</span> <span class="site-state-item-name">日志</span></a></div><div class="site-state-item site-state-tags"><a href="/tags/"><span class="site-state-item-count">63</span> <span class="site-state-item-name">标签</span></a></div></nav></div><div class="links-of-author animated"><span class="links-of-author-item"><a href="https://github.com/M-HALLIDAY" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;M-HALLIDAY" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i></a> </span><span class="links-of-author-item"><a href="mailto:halliday2023@163.com" title="E-Mail → mailto:halliday2023@163.com" rel="noopener me" target="_blank"><i class="fa fa-envelope fa-fw"></i></a> </span><span class="links-of-author-item"><a href="/atom.xml" title="RSS → &#x2F;atom.xml" rel="noopener me"><i class="fa fa-rss-square fa-fw"></i></a></span></div><div class="cc-license animated" itemprop="license"><a href="https://creativecommons.org/licenses/by-nc-sa/4.0/zh-CN" class="cc-opacity" rel="noopener" target="_blank"><img src="https://cdnjs.cloudflare.com/ajax/libs/creativecommons-vocabulary/2020.11.3/assets/license_badges/small/by_nc_sa.svg" alt="Creative Commons"></a></div></div></div></div></aside></div><div class="main-inner post posts-expand"><div class="post-block"><article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN"><link itemprop="mainEntityOfPage" href="http://kiki.kim/2022/03/11/python+behave+openpyxl%E7%AE%A1%E7%90%86%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B/"><span hidden itemprop="author" itemscope itemtype="http://schema.org/Person"><meta itemprop="image" content="https://halliday.oss-cn-nanjing.aliyuncs.com/imagesbjx.png"><meta itemprop="name" content="小梦同学"></span><span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization"><meta itemprop="name" content="随言碎语"><meta itemprop="description" content="欲买桂花同载酒,终不似,少年游。"></span><span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork"><meta itemprop="name" content="python+behave+openpyxl管理测试用例 | 随言碎语"><meta itemprop="description" content=""></span><header class="post-header"><h1 class="post-title" itemprop="name headline">python+behave+openpyxl管理测试用例</h1><div class="post-meta-container"><div class="post-meta"><span class="post-meta-item"><span class="post-meta-item-icon"><i class="far fa-calendar"></i> </span><span class="post-meta-item-text">发表于</span> <time title="创建时间2022-03-11 16:29:30" itemprop="dateCreated datePublished" datetime="2022-03-11T16:29:30+08:00">2022-03-11</time> </span><span class="post-meta-item"><span class="post-meta-item-icon"><i class="far fa-calendar-check"></i> </span><span class="post-meta-item-text">更新于</span> <time title="修改时间2023-05-11 12:48:55" itemprop="dateModified" datetime="2023-05-11T12:48:55+08:00">2023-05-11</time> </span><span class="post-meta-item" title="阅读次数" id="busuanzi_container_page_pv"><span class="post-meta-item-icon"><i class="far fa-eye"></i> </span><span class="post-meta-item-text">阅读次数:</span> <span id="busuanzi_value_page_pv"></span> </span><span class="post-meta-break"></span> <span class="post-meta-item" title="本文字数"><span class="post-meta-item-icon"><i class="far fa-file-word"></i> </span><span class="post-meta-item-text">本文字数:</span> <span>3.8k</span> </span><span class="post-meta-item" title="阅读时长"><span class="post-meta-item-icon"><i class="far fa-clock"></i> </span><span class="post-meta-item-text">阅读时长 &asymp;</span> <span>7 分钟</span></span></div></div></header><div class="post-body" itemprop="articleBody"><p>测试用例文本化使用python+behave来维护测试用例</p><span id="more"></span><h2 id="1-背景">1.背景</h2><p>测试用例一般都是用excel去维护的这也是行业内大部分公司的做法。</p><p>近期由于公司leader的要求“你们测试用例要文本化主要是方便diff不然每次提交的都是xls文件(测试用例会提交到git仓库)不太方便去比较。如果文本化了就能在git中直接看出这次提交修改的内容”。</p><p>基于这个需求其实有很多更好用的excel对比工具但是大佬是研发类型的大佬更希望能够文本化处理。即通过某种方式将写好的测试用例转成文本然后再通过CI/CD的方式编译出我们需要的excel。相当于提交到git仓库的不再是excel而是转换后的文本。</p><h2 id="2-项目介绍">2.项目介绍</h2><p>behave的介绍<a href="/2021/10/10/BDD-python+behave%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95%E6%90%AD%E5%BB%BA/" title="BDD-python+behave自动化测试搭建">BDD-python+behave自动化测试搭建</a></p><p>分两个部分一个是将excel转换为behave所需要的feature一个是将feature转换为excel从而达到相互转换的。</p><h2 id="2-1-将原有的excel转化为feature">2.1 将原有的excel转化为feature</h2><p>通常情况下excel的模板都是固定的。同公司中不同项目所使用的测试用应该是基于同一个模板编写的。</p><p>这里就是针对基于固定模板编写完成的测试用例文件进行分析并转换为feature文件</p><p>项目地址:<a target="_blank" rel="noopener" href="https://gitea.kiki.kim/ha/excel2feature.git">https://gitea.kiki.kim/ha/excel2feature.git</a></p><p>目录结构</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">+--excel2feature/</span><br><span class="line">| +--bin/ </span><br><span class="line">| | +-- e2f.py # -- 主程序</span><br><span class="line">| +--excel_files/ # -- 测试用例文件夹</span><br><span class="line">| | +-- *.xlsx # 测试用例</span><br><span class="line">| +--templates/ # -- features模板</span><br><span class="line">| | +-- *feature.j2 # 模板文件</span><br><span class="line">| +--output/ # -- 转换后的feature</span><br></pre></td></tr></table></figure><p>核心代码:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"> <span class="comment">#获取所有的数据</span></span><br><span class="line"> work_book = xlrd.open_workbook(self.xlsx_file_path)</span><br><span class="line"> <span class="comment">#为了让py2字典的顺序与py3一致</span></span><br><span class="line"> all_data = OrderedDict()</span><br><span class="line"> <span class="keyword">for</span> i, sheet_obj <span class="keyword">in</span> <span class="built_in">enumerate</span>(work_book.sheets()):</span><br><span class="line"> all_data[sheet_obj.name] = [sheet_obj.row_values(row)</span><br><span class="line"> <span class="keyword">for</span> row <span class="keyword">in</span> <span class="built_in">range</span>(sheet_obj.nrows)]</span><br><span class="line">.........</span><br><span class="line">.........</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">get_feature_data</span>(<span class="params">self, datas, sheet_name</span>):</span><br><span class="line"> <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string"> 根据sheet_name 处理数据</span></span><br><span class="line"><span class="string"> &quot;&quot;&quot;</span></span><br><span class="line"> context_temp = OrderedDict()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> sheet_name == <span class="string">&quot;封面&quot;</span>:</span><br><span class="line"> context_temp[<span class="string">&#x27;project&#x27;</span>] = self.project</span><br><span class="line"> context_temp[<span class="string">&#x27;sheet_name&#x27;</span>] = sheet_name</span><br><span class="line"> <span class="comment"># 处理更新记录</span></span><br><span class="line"> Scenario_table = []</span><br><span class="line"> lines = datas[<span class="number">4</span>:]</span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> lines:</span><br><span class="line"> cells = line</span><br><span class="line"> <span class="comment"># 处理换行</span></span><br><span class="line"> <span class="keyword">for</span> index, cell <span class="keyword">in</span> <span class="built_in">enumerate</span>(cells):</span><br><span class="line"> <span class="comment">#因为py2的编码问题不能判断str</span></span><br><span class="line"> <span class="comment">#isinstance(cell,str)</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(cell,(<span class="built_in">int</span>,<span class="built_in">float</span>)):</span><br><span class="line"> cells[index] = cell.replace(<span class="string">&#x27;\n&#x27;</span>, <span class="string">&#x27;\\n&#x27;</span>)</span><br><span class="line"> Scenario_table.append(cells)</span><br><span class="line"> context_temp[<span class="string">&#x27;Scenario_table&#x27;</span>] = Scenario_table</span><br><span class="line"></span><br><span class="line"> <span class="keyword">elif</span> sheet_name == <span class="string">&quot;统计表&quot;</span>:</span><br><span class="line"> context_temp[<span class="string">&#x27;project&#x27;</span>] = self.project</span><br><span class="line"> context_temp[<span class="string">&#x27;sheet_name&#x27;</span>] = sheet_name</span><br><span class="line">.........</span><br><span class="line">.........</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">feature_tpl</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string"> 拿处理后的数据来渲染指定的模板</span></span><br><span class="line"><span class="string"> &quot;&quot;&quot;</span></span><br><span class="line"> <span class="comment"># 读取模板</span></span><br><span class="line"> tpl = os.path.join(self.templates_dir, self.feature_name + <span class="string">&quot;.j2&quot;</span>)</span><br><span class="line"> tpl_data = io.<span class="built_in">open</span>(tpl, encoding=<span class="string">&quot;utf-8&quot;</span>).read()</span><br><span class="line"> <span class="comment"># 渲染模板</span></span><br><span class="line"> env = Environment()</span><br><span class="line"> text = env.from_string(tpl_data).render(self.context)</span><br><span class="line"> <span class="comment"># 保存文件</span></span><br><span class="line"> xl2fe.save_feature(self, text)</span><br><span class="line"></span><br><span class="line"> </span><br></pre></td></tr></table></figure><h2 id="2-2-将feature转换为excel">2.2 将feature转换为excel</h2><p>由于提交的都是feature文件这种方式是无法直接去使用的。因此需要再将其转为excel文件。</p><p>项目地址:<a target="_blank" rel="noopener" href="https://gitea.kiki.kim/ha/behave-test-case.git">https://gitea.kiki.kim/ha/behave-test-case.git</a></p><p>项目结构:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">+--behave-test-case/</span><br><span class="line">| +--bin/ </span><br><span class="line">| | +-- behave_main.py # -- 主程序</span><br><span class="line">| +--features/ </span><br><span class="line">| | +-- *.feature # 转换后的测试用例</span><br><span class="line">| +--fixtures/ # 模板文件目录</span><br><span class="line">| | +-- test_case_template.xlsx # 模板文件</span><br><span class="line">| +--output/ # -- 转换后的目录</span><br></pre></td></tr></table></figure><p>核心代码:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">激活sheet页</span></span><br><span class="line">@step(u&#x27;I active &quot;&#123;title&#125;&quot;&#x27;)</span><br><span class="line">def i_active_title(context,title):</span><br><span class="line"> # context.project_file = os.path.join(context.output_dir,context.file)</span><br><span class="line"> # context.wb = load_workbook(context.project_file)</span><br><span class="line"> #print(title)</span><br><span class="line"> context.ws = context.wb.get_sheet_by_name(title)</span><br><span class="line">.........</span><br><span class="line">.........</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">自动合并单元格</span></span><br><span class="line">@step(u&#x27;I auto_merge_cells &quot;&#123;col&#125;&quot; start at &quot;&#123;startnum&#125;&quot;&#x27;)</span><br><span class="line">def i_auto_merge_cells(context,col,startnum):</span><br><span class="line"> status = True</span><br><span class="line"> startnum = int(startnum)</span><br><span class="line"> endnum = startnum + 1</span><br><span class="line"> #print(endnum)</span><br><span class="line"> while status:</span><br><span class="line"> startcol = col + str(startnum)</span><br><span class="line"> endcol = col +str(endnum)</span><br><span class="line"> if context.ws[endcol].value == None or context.ws[endcol].value == &#x27;&#x27;:</span><br><span class="line"> status = False</span><br><span class="line"> #continue</span><br><span class="line"> if context.ws[startcol].value == context.ws[endcol].value:</span><br><span class="line"> endnum = endnum +1</span><br><span class="line"> else:</span><br><span class="line"> endnumtmp = endnum -1</span><br><span class="line"> endcoltmp = col +str(endnumtmp)</span><br><span class="line"> cells = startcol + &quot;:&quot; + endcoltmp</span><br><span class="line"> context.ws.merge_cells(cells)</span><br><span class="line"> context.ws[startcol].alignment = my_alignment(&#x27;center&#x27;, &#x27;center&#x27;)</span><br><span class="line"> startnum = endnum</span><br><span class="line"> endnum = endnum +1</span><br><span class="line">.........</span><br><span class="line">.........</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">写入数据</span></span><br><span class="line">@step(u&#x27;I load the table&#x27;)</span><br><span class="line">def i_load_table(context):</span><br><span class="line"> table = context.table</span><br><span class="line"> #print(table)</span><br><span class="line"> if context.text:</span><br><span class="line"> title = table.headings</span><br><span class="line"> context.ws.append(title)</span><br><span class="line"> lists = table.rows</span><br><span class="line"> for cells_list in lists:</span><br><span class="line"> cells = cells_list.cells</span><br><span class="line"> values = []</span><br><span class="line"> for cell in cells:</span><br><span class="line"> #换行符被转义了,再处理回来</span><br><span class="line"> cell_value = cell.replace(&#x27;\\n&#x27;,&#x27;\n&#x27;)</span><br><span class="line"> values.append(cell_value)</span><br><span class="line"> #print(values)</span><br><span class="line"> context.ws.append(values)</span><br><span class="line"></span><br></pre></td></tr></table></figure></div><footer class="post-footer"><div><div style="text-align:center;color:#ccc;font-size:24px;padding-top:10px">----- The End -----</div><div><center><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/social-share.js/1.0.16/css/share.min.css"><div class="social-share" data-sites="weibo, qq, qzone,wechat"></div><script src="http://apps.bdimg.com/libs/jquery/1.8.2/jquery.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/social-share.js/1.0.16/js/social-share.min.js"></script></center></div></div><div class="post-copyright"><ul><li class="post-copyright-author"><strong>本文作者: </strong>小梦同学</li><li class="post-copyright-link"><strong>本文链接:</strong> <a href="http://kiki.kim/2022/03/11/python+behave+openpyxl%E7%AE%A1%E7%90%86%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B/" title="python+behave+openpyxl管理测试用例">http://kiki.kim/2022/03/11/python+behave+openpyxl管理测试用例/</a></li><li class="post-copyright-license"><strong>版权声明: </strong>本博客所有文章除特别声明外,均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/zh-CN" rel="noopener" target="_blank"><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处!</li></ul></div><div class="post-tags"><a href="/tags/python/" rel="tag"><i class="fa fa-tag"></i> python</a> <a href="/tags/behave/" rel="tag"><i class="fa fa-tag"></i> behave</a> <a href="/tags/%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95/" rel="tag"><i class="fa fa-tag"></i> 自动化测试</a> <a href="/tags/%E6%B5%8B%E8%AF%95/" rel="tag"><i class="fa fa-tag"></i> 测试</a></div><script type="text/javascript">for(var tagsall=document.getElementsByClassName("post-tags"),i=tagsall.length-1;0<=i;i--)for(var tags=tagsall[i].getElementsByTagName("a"),j=tags.length-1;0<=j;j--){var r,g,b,golden_ratio=.618033988749895,s=.5,v=.999,h=golden_ratio+.8*Math.random()-.5,h_i=parseInt(6*h),f=6*h-h_i,p=v*(1-s),q=v*(1-f*s),t=v*(1-(1-f)*s);switch(h_i){case 0:r=v,g=t,b=p;break;case 1:r=q,g=v,b=p;break;case 2:r=p,g=v,b=t;break;case 3:r=p,g=q,b=v;break;case 4:r=t,g=p,b=v;break;case 5:r=v,g=p,b=q;break;default:b=g=r=1}tags[j].style.background="rgba("+parseInt(255*r)+","+parseInt(255*g)+","+parseInt(255*b)+",0.5)"}</script><div class="post-nav"><div class="post-nav-item"><a href="/2022/02/27/centos7%E5%AE%89%E8%A3%85docker/" rel="prev" title="centos7安装docker"><i class="fa fa-chevron-left"></i> centos7安装docker</a></div><div class="post-nav-item"><a href="/2022/03/20/%E9%80%9A%E8%BF%87certbot+nginx%E7%94%B3%E8%AF%B7%E6%B3%9B%E5%9F%9F%E5%90%8D%E8%AF%81%E4%B9%A6/" rel="next" title="通过certbot+nginx申请泛域名证书">通过certbot+nginx申请泛域名证书 <i class="fa fa-chevron-right"></i></a></div></div></footer></article></div></div></main><footer class="footer"><div class="footer-inner"><div class="copyright">&copy; <span itemprop="copyrightYear">2023</span> <span class="with-love"><i class="fa fa-heart"></i> </span><span class="author" itemprop="copyrightHolder">小梦同学</span></div><div class="beian"><img src="https://www.beian.gov.cn/img/new/gongan.png" alt=""><a href="https://www.beian.gov.cn//portal/registerSystemInfo?recordcode=%E7%94%B3%E8%AF%B7%E4%B8%AD" rel="noopener" target="_blank">申请中 </a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://beian.miit.gov.cn/" rel="noopener" target="_blank">苏ICP备2021047152号-1</a></div><div class="busuanzi-count"><span class="post-meta-item" id="busuanzi_container_site_uv"><span class="post-meta-item-icon"><i class="fa fa-user"></i> </span><span class="site-uv" title="总访客量"><span id="busuanzi_value_site_uv"></span> </span></span><span class="post-meta-item" id="busuanzi_container_site_pv"><span class="post-meta-item-icon"><i class="fa fa-eye"></i> </span><span class="site-pv" title="总访问量"><span id="busuanzi_value_site_pv"></span></span></span></div><div class="powered-by"><a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动</div><span id="timeDate">载入天数...</span> <span id="times">载入时分秒...</span><script>var now=new Date;function createtime(){var n=new Date("03/01/2023 10:00:00");now.setTime(now.getTime()+250),days=(now-n)/1e3/60/60/24,dnum=Math.floor(days),hours=(now-n)/1e3/60/60-24*dnum,hnum=Math.floor(hours),1==String(hnum).length&&(hnum="0"+hnum),minutes=(now-n)/1e3/60-1440*dnum-60*hnum,mnum=Math.floor(minutes),1==String(mnum).length&&(mnum="0"+mnum),seconds=(now-n)/1e3-86400*dnum-3600*hnum-60*mnum,snum=Math.round(seconds),1==String(snum).length&&(snum="0"+snum),document.getElementById("timeDate").innerHTML="本站已安全运行 "+dnum+" 天 ",document.getElementById("times").innerHTML=hnum+" 小时 "+mnum+" 分 "+snum+" 秒."}setInterval("createtime()",250)</script></div></footer><div class="back-to-top" role="button" aria-label="返回顶部"><i class="fa fa-arrow-up fa-lg"></i> <span>0%</span></div><div class="reading-progress-bar"></div><a href="https://github.com/M-HALLIDAY" class="github-corner" title="在 GitHub 上关注我" aria-label="在 GitHub 上关注我" rel="noopener" target="_blank"><svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin:130px 106px" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><noscript><div class="noscript-warning">Theme NexT works best with JavaScript enabled</div></noscript><script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js" integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js" integrity="sha256-yt2kYMy0w8AbtF89WXb2P1rfjcP/HTHLT7097U8Y5b8=" crossorigin="anonymous"></script><script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/next-boot.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script><script src="/js/third-party/search/local-search.js"></script><script src="/js/third-party/fancybox.js"></script><script src="/js/third-party/pace.js"></script><script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><script src="https://unpkg.com/darkmode-js@1.5.7/lib/darkmode-js.min.js"></script><script>var options = {
bottom: '64px',
right: 'unset',
left: '32px',
time: '0.5s',
mixColor: 'transparent',
backgroundColor: 'transparent',
buttonColorDark: '#100f2c',
buttonColorLight: '#fff',
saveInCookies: true,
label: '🌓',
autoMatchOsTheme: true
}
const darkmode = new Darkmode(options);
window.darkmode = darkmode;
darkmode.showWidget();</script><script async src="/js/cursor/love.min.js"></script><script type="text/javascript" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script></body></html>