Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bdd testing: easy testing of arrays #3268

Closed
Tracked by #5010
vixalien opened this issue Mar 19, 2023 · 5 comments
Closed
Tracked by #5010

bdd testing: easy testing of arrays #3268

vixalien opened this issue Mar 19, 2023 · 5 comments
Labels
needs information Requires further information

Comments

@vixalien
Copy link

Is your feature request related to a problem? Please describe.

Yes. currently, it's not very easy to test arrays of data. For example, I'm writing a library that parses (rather complex) musical data into reusable JSON structures.

Take this example:

const data = get_data() as Data;

interface Data {
  title: string;
  categories: {
    title: string;
    results: (Playlist | Song | Album | Artist | ...)[];
  };
}

this is how I'm testing this currently

describe("data", () => {
  let data: Data;

  beforeAll(async () => {
    data = await get_data();
  })

  it("title", () => {
    assertEquals(typeof title, "string");
  });

  describe("categories", () => {
    it("present", () => {
      assert(data.categories.length > 0);
    });

    describe("category", () => {
      let category: any;

      beforeAll(() => {
        category = data.categories[0];
      });

      it("name", () => {
        assert(category.name.length > 0);
      });
  
      it("params", () => {
        assert(category.params.length > 0);
      });

      // I'm not even testing `category.results`, it's too complex
    })
  })
});

Describe the solution you'd like

It would be nice if for example the describe function could take in arrays I'm not sure (or an iterator).

describe("category", () => {
  let category: any;
  let id = 0;

  // Notice this is a generator function
  // this would be run each time unless it doesnt yield something
  beforeAll(* () => {
    while (true) {
      if (id >= data.categories.length) {
        break;
      }
      yield category = data.categories[id++];
    }
  });

  it("name", () => {
    assert(category.name.length > 0);
  });

  it("params", () => {
    assert(category.params.length > 0);
  });
})

or maybe something attached to describe

describe(
  "category",
  forEach = (id: number) => {
    this.category = data.categories[id];
    return id < data.categories.length;
  },
  fn() {
    it("name", function (this: { category: any }) => {
      assert(this.category.name.length > 0);
    });

    it("params", function (this: { category: any }) {
      assert(this.category.params.length > 0);
    });
  },
);

Describe alternatives you've considered

I've tried many alternatives, but no one really worked. right now I'm just using asserts (hence throwing away the benefits of bdd

data.categories.forEach((category) => {
  assertEqual(typeof category, "string"); 
  // etc...
)
@KyleJune
Copy link
Contributor

KyleJune commented May 4, 2023

You can call it or describe in a for loop or a forEach block. Here is an example based on code samples you provided. In it, it will register a test group for each category with names in the format category[0], but you could construct the names to be whatever you want, even using variables from the category object. Then for each category, it would register 2 test steps, one for name and one for params.

data.categories.forEach((category, index) => {
  describe(`category[${index}]`, () => {
    it("name", () => {
      assert(category.name.length > 0);
    });

    it("params", () => {
      assert(category.params.length > 0);
    });
  });
});

If you have tests you only want to run for specific types of category objects, you could use if blocks to conditionally register different types of tests. And it doesn't all have to be in a single for loop or forEach, you could create functions for registering sets of tests then conditionally call them.

The describe/it function's are pretty flexible. I would personally prefer not adding something like the 2 examples provided. I believe it would make it more confusing to read and write test cases. In your first example, one might miss that there is a generator in their beforeAll when reading the test cases. For both examples, I'd have another question, which is what would the names for each of those cases generated? With the example I wrote, I believe it's much more clear how the test cases are being registered and what the names will be.

@vixalien
Copy link
Author

vixalien commented May 4, 2023

I can't do data.categories.forEach because data itself is loaded in a beforeAll.

I haven't found a way to load data directly so this can't work.

@iuioiua iuioiua mentioned this issue Jun 26, 2024
8 tasks
@kt3k kt3k added the needs information Requires further information label Jun 26, 2024
@kt3k
Copy link
Member

kt3k commented Jun 26, 2024

I can't do data.categories.forEach because data itself is loaded in a beforeAll.

Why is data not available at top-level, but available at beforeAll?

Have you tried beforeEach for running some process before each case?

@vixalien
Copy link
Author

Why is data not available at top-level, but available at beforeAll?

I don't remember the reason anymore, but I believe it's because if you fetch data outside the test functions, sometimes the data is not available inside the describe/it functions.

It's been some time since I last touched this, but I also think Deno was complaining about data not being cleaned up or similar.

@kt3k
Copy link
Member

kt3k commented Jun 27, 2024

Thanks for your reply.

I'm closing this issue for now because you don't seem needing it anymore.

Please re-open this issue or create a new one if you find a similar situation, and still find this is an issue

@kt3k kt3k closed this as completed Jun 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs information Requires further information
Projects
None yet
Development

No branches or pull requests

3 participants