
Post by tew468 on Jan 2, 2020 22:24:24 GMT
Hi, I'm working my way through using Python/Numpy (which I'm familiar with), and learning Behave/Cucumber/Gherkin (which is new to me).
I've been doing okay with creating the Python "step" files for converting the .feature files to runnable tests until I got to chapter 3 for assigning matrices. What is a reasonable method to "read" a Gherkin matrix in a "@given" statement into a numpy matrix? For instance, for vectors, I can map the Gherkin line: Given c1 ← color(0.9, 0.6, 0.75) using the following: @given("{item:TestVariable} ← color({x:g}, {y:g}, {z:g})") def step_impl_color(context,item,x,y,z): try: if (context.tuple is None): context.tuple = {} except: context.tuple = {} context.tuple[item] = base.Vec3(float(x), float(y), float(z))
where "base.Vec3" is my 3element vector class, and "TestVariable" is a set of restricted inputs. I'm not sure how to create the corresponding python @given implementation for the case: Given the following 4x4 matrix M:  1  2  3  4   5.5  6.5  7.5  8.5   9  10  11  12   13.5  14.5  15.5  16.5  Any suggestions / pointers to reference implementations of this kind of thing using Python's Behave module? Thanks in advance,
Tom



Post by tew468 on Jan 6, 2020 5:45:00 GMT
Update  for now, I've just opted to change the syntax of the .feature files, so the Scenario Gherkin text becomes: Scenario: Constructing and inspecting a 4x4 matrix Given the following 4x4 matrix M: [[1, 2, 3, 4], [5.5, 6.5, 7.5, 8.5], [9, 10, 11, 12], [13.5, 14.5, 15.5, 16.5]] Then M[0,0] = 1 And M[0,3] = 4 And M[1,0] = 5.5 And M[1,2] = 7.5 And M[2,2] = 11 And M[3,0] = 13.5 And M[3,2] = 15.5
I'm then just parsing the string with eval() in the matrix_steps.py file:
from behave import * from hamcrest import assert_that, equal_to from parse_type import TypeBuilder import numpy as np
# create the "type" representing the various matrix names valid_test_matrices = ["M", "A", "B", "C", "inv", "half_quarter"] parse_test_matrix = TypeBuilder.make_choice(valid_test_matrices) register_type(TestMatrix=parse_test_matrix)
# "matrix" is left as an untyped string to be parsed by "eval()" @given("the following {height:g}x{width:g} matrix {item:TestMatrix}: {matrix}") def step_impl_matrix(context, height, width, item, matrix): try: if (context.dict is None): context.dict = {} except: context.dict = {} new_matrix_string = "np.array(" + matrix + ", dtype=float)" new_matrix = eval(new_matrix_string) assert (new_matrix.shape == (height, width)) context.dict[item] = new_matrix



Post by Jamis on Jan 6, 2020 20:49:03 GMT
I'm glad you found a workaround. I'm afraid I don't have any experience with using Cucumber with Python, so I can't speak to your original question. In the Ruby implementation of Cucumber, I seem to recall that there are implementation hooks you can employ to process the tables; maybe there is something similar in Python? I'm sorry I can't be more helpful!
 Jamis



Post by tew468 on Jan 9, 2020 17:35:42 GMT
Not a problem; I just figured it was worth asking in case there was something easy and obvious I was missing.
I've really been enjoying the book, both as a graphics refresher as well as an introduction to the Cucumber/Behave testdriven development paradigm. This is sortof like the software equivalent of building a HeathKit shortwave radio in the 80s. Tom

