Data-Test-Executer Framework speziell zum Test von Datenverarbeitungen mit Datengenerierung, Systemvorbereitungen, Einspielungen, ganzheitlicher diversifizierender Vergleich
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
9.3 KiB

#!/usr/bin/python
# -*- coding: utf-8 -*-
# ---------------------------------------------------------------------------------------------------------
# Author : Ulrich Carmesin
# Source : gitea.ucarmesin.de
# ---------------------------------------------------------------------------------------------------------
import os
import traceback
import basic.toolHandling
import tools.data_tool
import tools.job_const as J
import tools.data_const as D
import basic.constants as B
import model.entity
import tools.config_tool
import tools.job_tool
import tools.path_tool
import tools.path_const as P
import model.entity
import model.story
import model.datatable
import model.step
import model.factory
import tools.file_type
TABLE_NAMES = ["application", "ap_project", "ap_component"]
STORAGES = [model.entity.STORAGE_FILE, model.entity.STORAGE_DB]
""" used storage in priority sortage, so: if file then read_fcts / if db then select-fcts """
DEFAULT_SYNC = model.entity.SYNC_FULL_GIT2DB
TABLE_NAME = B.SUBJECT_APP
""" system-name for this entity """
FIELD_ID = "tcid"
LIST_SUB_DESCRIPT = [D.DATA_ATTR_USECASE_DESCR, D.DATA_ATTR_STORY_DESCR]
FILE_EXTENSION = D.DFILE_TYPE_YML
UNIQUE_FIELDS = [D.FIELD_NAME]
""" unique business field as human identifer """
IDENTIFYER_FIELDS = [FIELD_ID]
""" unique technical field as technical identifer """
class Testcase(model.entity.Entity):
"""
Generally this object can be stored as a file with data or in a database.
references:
application ->
story -> story
variant -> comp.step
subtables
steps -> comp.step
tables -> comp.table
"""
FIELD_ID = "tcid"
LIST_FIELDS = [FIELD_ID, D.FIELD_NAME, B.SUBJECT_APP,
B.SUBJECT_DESCRIPTION, B.SUBJECT_REFERENCE, B.SUBJECT_PROJECT]
LIST_NODES = [B.NODE_ATTRIBUTES]
LIST_SUBTABLES = [B.SUBJECT_VARIANTS, B.SUBJECT_USECASES, B.SUBJECT_STORIES, B.SUBJECT_DATATABLES, B.SUBJECT_STEPS]
tcid = ""
name = ""
description = ""
project = ""
reference = ""
attributes = ""
1 year ago
stories = {}
tables = {}
1 year ago
steps = {}
def read_unique_names(self, job, project, application, gran, args, ttype: str=""):
"""
reads the entity-names from file-storage
:param job:
:param opt. project: select-criteria if used and defined
:param opt. application: select-criteria if used and defined
:param opt. gran: granularity values testcase / testsuite / testplan
:param opt. args additional args
:return: list of entity-names
"""
1 year ago
if project == "":
project = getattr(job.par, B.SUBJECT_PROJECT)
path = os.path.join(job.conf[B.TOPIC_PATH][B.ATTR_PATH_TDATA], project,
B.SUBJECT_TESTCASES)
outList = self.getDirlist(job, path, "")
return outList
def read_entity(self, job, name):
"""
reads the entity from the file-system
:param job:
:param name:
:return:
"""
# r = tools.config_tool.select_config_path(job, P.KEY_TESTCASE, "TC0001")
# ttype=testcase => Aufteilung der Testspec in Bloecke und separater Aufruf zur Pruefung der Bloecke
config = self.getConfig(job, P.KEY_TESTCASE, name, tools.config_tool.get_plain_filename(job, name), B.SUBJECT_TESTCASE)
self.setAttributes(job, config, name, self.LIST_FIELDS, self.LIST_NODES, self.LIST_SUBTABLES)
return self
@staticmethod
def rebuild_data(job, data: dict) -> dict:
"""
gets the subtable-tag from filecsv and sets the subtables in order to workable entity-elements
:param job:
:param data:
:return:
"""
data = tools.file_type.popSubjectsNode(job, data)
# data = tools.file_type.popNameNode(job, data)
data = Testcase.buildHeadAttributes(job, data, Testcase.LIST_FIELDS, Testcase.LIST_SUBTABLES)
return data
@staticmethod
def buildHeadAttributes(job, data: dict, fields: list, subtables: list) -> dict:
"""
workaround for _head:attr resp _option:attr
:param data:
:param head:
:return:
"""
outdata = {}
attributes = {}
subtable = {}
xsubtable = {}
try:
for k in data:
if k in [B.DATA_NODE_HEAD, B.DATA_NODE_OPTION]:
if k not in outdata:
outdata[k] = {}
xkeys = []
for l in data[k]:
a = l.split("-")
val = data[k][l]
if tools.data_tool.getPluralKeyword(a[0]) in B.LIST_SUBJECTS \
and tools.data_tool.getSingularKeyword(a[0]) in fields:
outdata[tools.data_tool.getSingularKeyword(a[0])] = tools.data_tool.splitDelimitedValues(val)[0]
elif tools.data_tool.getPluralKeyword(a[0]) in B.LIST_SUBJECTS \
and tools.data_tool.getPluralKeyword(a[0]) in subtables:
xsubtable = Testcase.setSubtable(job, xsubtable, l, val, outdata)
#outdata[tools.data_tool.getPluralKeyword(a[0])] = subtable
elif k == B.DATA_NODE_OPTION:
attributes[l] = data[k][l]
else:
outdata[k][l] = data[k][l]
elif k in B.LIST_DATA_NODE and tools.data_tool.getPluralKeyword(k) in subtables:
outdata[tools.data_tool.getPluralKeyword(k)] = data[k]
else:
outdata[k] = data[k]
if len(outdata[B.DATA_NODE_OPTION]) == 0:
outdata.pop(B.DATA_NODE_OPTION)
if len(outdata[B.DATA_NODE_HEAD]) == 0:
outdata.pop(B.DATA_NODE_HEAD)
outdata[B.NODE_ATTRIBUTES] = attributes
for k in xsubtable:
if k == "xkeys":
continue
outdata[k] = xsubtable[k]
except Exception as e:
print(traceback.format_exc())
pass
return outdata
@staticmethod
def setSubtable(job, xsubtable, key: str, val: str, data: dict):
a = key.split("-")
if tools.data_tool.getPluralKeyword(a[0]) not in xsubtable:
xkeys = []
subtable = {}
for x in tools.data_tool.splitDelimitedValues(val):
if x == "" or x[:1] == "#": break
subtable[x] = {D.FIELD_NAME: x}
xkeys.append(x)
else:
subtable = xsubtable[tools.data_tool.getPluralKeyword(a[0])]
i = 0
vals = tools.data_tool.splitDelimitedValues(val)
xkeys = xsubtable["xkeys"]
for x in xkeys:
subtable[x][a[1]] = vals[i]
i += 1
xsubtable["xkeys"] = xkeys
xsubtable[tools.data_tool.getPluralKeyword(a[0])] = subtable
return xsubtable
@staticmethod
def check_data(job, data: dict) -> dict:
checkNodes = {}
checkNodes[tools.file_type.MUST_NODES] = [B.SUBJECT_APP, B.SUBJECT_DATATABLES, B.SUBJECT_STEPS, B.SUBJECT_VARIANTS,
B.NODE_ATTRIBUTES]
checkNodes[tools.file_type.MUSTNT_NODES] = [B.DATA_NODE_OPTION, B.DATA_NODE_DATA, B.DATA_NODE_FIELDS, B.DATA_NODE_HEADER]
checkNodes[tools.file_type.OPT_NODES] = [B.SUBJECT_USECASES, B.SUBJECT_STORIES]
return tools.file_type.check_nodes(job, data, checkNodes)
def select_entity(self, job, name):
"""
reads the entity from the database
it should get the same result like read_entity
:param job:
:param name:
:return:
"""
return self.read_entity(job, name)
def select_testcase(job, project, testcase):
"""
to select a concrete testcase
:param job:
:param project:
:param testcase:
:return:
"""
jobProj = None
if hasattr(job.par, B.PAR_PROJ):
jobProj = getattr(job.par, B.PAR_PROJ)
setattr(job.par, B.PAR_PROJ, project)
path = tools.path_tool.compose_path(job, P.P_TDROOT, None)
specpath = os.path.join(path, testcase, D.DFILE_TESTCASE_NAME + ".csv")
spec = model.entity.read_spec(job, testcase, J.GRAN_TS, specpath)
if jobProj is None:
delattr(job.par, B.PAR_PROJ)
else:
setattr(job.par, B.PAR_PROJ, jobProj)
print("select_testcase "+str(spec))
return spec
def select_testcases(job, projList, appList):
out = {}
jobProj = None
if hasattr(job.par, B.PAR_PROJ):
jobProj = getattr(job.par, B.PAR_PROJ)
for proj in projList:
setattr(job.par, B.PAR_PROJ, proj)
path = tools.path_tool.compose_path(job, P.P_TDROOT, None)
if os.path.exists(path):
for d in os.listdir(path):
if not os.path.isdir(os.path.join(path, d)):
continue
if d[0:1] == "_":
continue
specpath = os.path.join(path, d, D.DFILE_TESTCASE_NAME + ".csv")
spec = model.entity.read_spec(job, d, J.GRAN_TS, specpath)
if spec is None:
continue
out[d] = spec
out[d][B.SUBJECT_PROJECTS] = [proj]
if jobProj is None:
delattr(job.par, B.PAR_PROJ)
else:
setattr(job.par, B.PAR_PROJ, jobProj)
return out