KazuCocoa / ex_parameterized

This library support parameterized test with test_with_params macro.
https://github.com/KazuCocoa/ex_parameterized
MIT License
29 stars 7 forks source link

Add a describe_with_params #14

Closed dylan-chong closed 6 years ago

dylan-chong commented 6 years ago

There would be useful to parameterise many tests at once. described_with_params would reduce the amount of boilerplate required to do this

KazuCocoa commented 6 years ago

Could you put an example? @dylan-chong

In general, the describe is used to separate contexts for each test cases. If we'd like to run parameterized tests in the context, we can use test_with_params with the current implementation.

describe "context1" do
  test "concrete test case1" do
    # ...
  end

  test "concrete test case2" do
    # ...
  end
end

Do you mean you have a situation like the following and you'd like to implement them with the parameterized test style?

describe "context1" do
  test "concrete test case1" do
    # ...
  end

  test "concrete test case2" do
    # ...
  end
end

describe "context2" do
  test "concrete test case1" do
    # the test case is same as context1's "concrete test case1" but some parameters are different
  end

  test "concrete test case2" do
    # the test case is same as context1's "concrete test case2" but some parameters are different
  end
end

In this case, each context has different situations and we shouldn't skip describing each context, I believe.

KazuCocoa commented 6 years ago

In the above case, we can also separate the following and in this case, and we can use test_with_params as well.

describe "test case 1" do
  test "context1's parameter" do
    # ...
  end

  test "context2's parameter" do
    # ...
  end
end
dylan-chong commented 6 years ago

In these tests here:

  describe "with strict_keys: false" do
    test_with_params "new still creates",
    fn module ->
      expected = Kernel.struct!(module, [a: 1])
      assert expected == module.new(a: 1)
    end, do: TestModules.test_modules()

    test_with_params "put still updates data successfully",
    fn module ->
      expected = Kernel.struct!(module, [a: 2])
      assert expected == [a: 1] |> module.new() |> module.put(a: 2)
    end, do: TestModules.test_modules()

    test_with_params "new ignores invalid keys",
    fn module ->
      expected = Kernel.struct!(module, [a: 1])
      assert expected == module.new(a: 1, invalid_key: 2)
    end, do: TestModules.test_modules()

    test_with_params "put ignores invalid keys",
    fn module ->
      expected = Kernel.struct!(module, [a: 1])
      assert expected == module.put(
        module.new(a: 1),
        invalid_key: 2
      )
    end, do: TestModules.test_modules()

    test_with_params "new does not check for enforced keys",
    fn module ->
      expected = Kernel.struct!(module, [a: nil])
      assert expected == module.new([])
    end, do: TestModules.test_modules()
  end

There is a bit of duplication regarding the parameterisation although i have tried to reduce duplication by putting the actual parameters in a method.

I guess what i was looking for is a way to parameterise a whole group of tests with a simplified parameterisation syntax. As a rough draft:

  describe_with_params "tests with the same parameters",
  [
    {:params1},
    {:params2},
  ],
  fn param -> 
    test "test 1" do
      do stuff with param
    end
    test "test 2" do

    end
  end

Although now that i think about it, it sounds pretty tricky to implement... Perhaps there is another way to solve this problem...

KazuCocoa commented 6 years ago

Thanks for your example and I understood your situation 👍

But as you mentioned the above, I also couldn't come up with a good idea to implement keep the implementation simple...

I close this issue once because of ^ and I'll re-open again if I find good way to implement it.