📜  使用 pycfg 绘制控制流图 | Python

📅  最后修改于: 2022-05-13 01:55:12.729000             🧑  作者: Mango

使用 pycfg 绘制控制流图 | Python

先决条件:控制流图,圈复杂度

通常,我们通过分析程序的控制流来使用笔和纸绘制手动控制流图。 CFG 帮助我们找到独立的路径(循环复杂度),这会导致测试程序所需的测试用例数量。我们可以使用名为 pycfg 的Python库自动执行 CFG 任务。该库将Python脚本作为输入,并将图形作为输出。

我们可以通过以下两种方式使用 pycfg

  1. 通过直接使用文件
  2. 通过在程序中导入库

通过直接使用文件

  1. 下载 pycfg tar 文件
  2. 解压它
  3. 使用pycfg.py文件

注意:解压后的 pycfg.py 文件位置为pycfg-0.1/pycfg/pycfg.py

让我们使用whiletest.py文件来获取 CFG。

a= 10
while(a <= 0):
    if a == 5:
        print(a)
    a += 1
print("exited")

在终端上运行以下命令。

python path_to/pycfg.py path_to/whiletest.py -d

输出:

这种方法以具有节点、标记的句子、节点之间的边的图形的形式给出输出。

通过在程序中导入库

在导入 linrary 和 tkinter 的帮助下,我们可以做得比单独使用pycfg.py文件要好得多。

  • 代表 CFG 而不是终端。
  • 也找到圈复杂度

运行以下命令

sudo pip install pycfg

完成后,使用相同的whiletest.py进行测试。我们可以在whiletest.py上运行以下Python程序。

python /path_to/this_file.py /path_to/whiletest.py

下面是代码——

from pycfg.pycfg import PyCFG, CFGNode, slurp
import argparse
import tkinter as tk
from PIL import ImageTk, Image
  
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
  
    parser.add_argument('pythonfile', help ='The python file to be analyzed')
    args = parser.parse_args()
    arcs = []
  
    cfg = PyCFG()
    cfg.gen_cfg(slurp(args.pythonfile).strip())
    g = CFGNode.to_graph(arcs)
    g.draw(args.pythonfile + '.png', prog ='dot')
  
    # Draw using tkinter.
    root = tk.Tk()
    root.title("Control Flow Graph")
    img1 = Image.open(str(args.pythonfile) + ".png")  # PIL solution
    img1 = img1.resize((800, 600), Image.ANTIALIAS)
    img = ImageTk.PhotoImage(img1)
      
    background ="gray"
  
    panel = tk.Label(root, height = 600, image = img)
    panel.pack(side = "top", fill ="both", expand = "yes")
    nodes = g.number_of_nodes()     # no. of nodes.
    edges = g.number_of_edges()     # no. of Edges.
    complexity = edges - nodes + 2         # Cyclomatic complexity
  
    frame = tk.Frame(root, bg = background)
    frame.pack(side ="bottom", fill ="both", expand = "yes")
          
    tk.Label(frame, text ="Nodes\t\t"+str(nodes), bg = background).pack()
    tk.Label(frame, text ="Edges\t\t"+str(edges), bg = background).pack()
    tk.Label(frame, text ="Cyclo Complexity\t"+
             str(complexity), bg = background).pack()
  
    root.mainloop()

输出:

参考: https://pypi.org/project/pycfg/