Hi again :-)

So I tried to write couple of RSpec test since we last talked, I'll mention 
again I'm writing couple end to end tests to verify all micro-services are 
up and running. Please consider the following example. It's an 
authentication service, that can create users. Before user is being 
created, a schema for the user-type needs to be created on a different 
micro-service:

RSpec.describe 'Authentication' do
  subject { AuthenticationService.new }
  let(:user_schema) { SchemaService.new }

  context 'When creating a user that does not exists ' do
    it 'response with status code 200 (success)' do
      schema_name = SecureRandom.uuid.to_s
      user_schema.create_schema(schema_name)
      payload = JSON.parse(File.read('spec/acceptence/fixtures/feature.json'
))
      payload['schema_name'] = schema_name

      response = subject.create_user(user: 'my_user', payload: payload)

      expect(response.code).to eq 200
    end

    it 'creates a new user' do
      schema_name = SecureRandom.uuid.to_s
      user_schema.create_schema(schema_name)      
      payload = JSON.parse(File.read('spec/acceptence/fixtures/feature.json'
))
      payload['schema_name'] = schema_name

      subject.create_user(user: 'my_user', payload: payload)

      response = subject.get_user_by_category(category: payload['category'])
      remote_entity = JSON.parse(response.body)

      expect(payload.to_json).to eq(
        remote_entity['list'][unique_value]
      )
    end
  end
end  

To keep it dry, I should be moving the whole schema creation into a before 
block:

before 
  schema_name = SecureRandom.uuid.to
  user_schema.create_schema(schema_name) 
end

Before makes sense to me over let here, because it's an action. However, 
because the schema is more of a 'pre-condition', I can create it just once, 
and avoid multiple schema in my database. Therefore, before(:all) seems 
like a better option.

before(:all)
  schema_name = SecureRandom.uuid.to_s
  user_schema.create_schema(schema_name) 
end

Now that problem is that when I create user in my examples, I NEED to 
schema name, so I need to share context between the before and it block. It 
makes sense for me to do it like so:

let(:schema_name) { SecureRandom.uuid.to_s }

before(:all)
  user_schema.create_schema(schema_name) 
end

Then I can create easily create user in my example like so:

payload = JSON.parse(File.read('spec/acceptence/fixtures/feature.json'))
payload['schema_name'] = schema_name

subject.create_user(user: 'my_user', payload: payload)

Alas, this will not work. As it not allowed by RSpec to use  a let value 
inside a before(:all) block. So I need to hold a string that can be used in 
both the it and before block. It can solved it by defining a Constant or 
using Instance variable but both methods feels reek to me. I mentioned I 
don't have access to the database (as those are remote machines and they 
don't expose the ip for that database) so I can't truncate the db 
information and avoid the before block here.

Thanks! 

On Thursday, July 20, 2017 at 10:57:05 AM UTC+3, Jon Gordon wrote:
>
> Not in Unit-tests of-course, but It seems like the only option in real 
> end-to-end testing. The system is quite complex, as it's basically a set of 
> couple micro-services. Each has it's own unique database (Can be Postgress, 
> Casanda, Oracle...). In a single End to End test, all databases are 
> populated with information. Clearing tables between each test can take 
> time, and is quite complex. The CI process does re-start the containers at 
> the very start of the test-run (so it's like restarting them to a fresh 
> state), but not during tests. 
>
> if I'll take the list of music instruments in the Faker gem for example, 
> It only has around 10 options. So even if I use the unique flag - It will 
> run out of options after 10 test-cases.  I guess use 'msuic instruments' 
> in one spec file, and 'cat-names' on the other to avoid it, but that means 
> I need to 'remember' what pool of string I already used in previous tests, 
> and that's feel even worse for me.
>
> Thanks.
>
>
>
> but I thought that there no better way around it. Because
>
> On Thursday, July 20, 2017 at 3:29:25 AM UTC+3, Myron Marston wrote:
>>
>> In general, if you need absolutely unique strings, `SecureRandom.uuid` is 
>> a good way to get one.  UUIDs are universally unique, after all :).
>>
>> That said, the fact that you are running out of unique random strings 
>> from faker is concerning.  All tests should work off of a "clean slate" in 
>> your database, either by wrapping each test in a rolled-back transaction, 
>> or by truncating your DB tables.  Are you "leaking" DB records between 
>> tests?
>>
>> Myron
>>
>> On Wed, Jul 19, 2017 at 12:42 PM, Jon Gordon <[email protected]> wrote:
>>
>>> Hi Myron, 
>>>
>>> I will definitely check the book - looks like it's perfect for RSpec 
>>> beginner. Also, thanks for sharing the example online - that's alone can 
>>> give me a good starting base :)
>>>
>>> I will ask another question while posting -  for unit-testing I'm using 
>>> Faker gem to fake common strings. However, in end to end tests, we work 
>>> against a database - so even if I'm using the 'unique' method, I'm running 
>>> out of unique strings after a while. I'm using 'securerandom' to generate 
>>> random number, but wondering if there's a better approach for that.
>>>
>>> Thanks!
>>>
>>> On Wednesday, July 19, 2017 at 6:33:49 PM UTC+3, Myron Marston wrote:
>>>>
>>>> My upcoming book, Effective Testing with RSpec 3 
>>>> <https://www.google.com/url?q=https%3A%2F%2Fpragprog.com%2Fbook%2Frspec3%2Feffective-testing-with-rspec-3&sa=D&sntz=1&usg=AFQjCNHGLaAn9OUSvszwbNhLSkP9Ypy-7A>,
>>>>  
>>>> has an example of building a JSON API using end-to-end acceptance tests, 
>>>> isolated unit tests, and integration tests.  It might fit what you're 
>>>> looking for better since you mentioned you're looking for examples of 
>>>> end-to-end testing of REST services.
>>>>
>>>> The code for the book is all online <https://github.com/rspec-3-book>, 
>>>> as well.
>>>>
>>>> All that said, Xavier's screen cast is very good, and I definitely 
>>>> recommend it, particularly if you do better with videos than printed 
>>>> materials.
>>>>
>>>> Myron
>>>>
>>>> On Wed, Jul 19, 2017 at 4:30 AM, Jon Gordon <[email protected]> wrote:
>>>>
>>>>> Thanks Xavier :)
>>>>> I will be checking this course!
>>>>>
>>>>> Is there perhaps an open-source project with end-to-end spec tests you 
>>>>> can recommend (REST tests are preferred, not Capybara)? something to get 
>>>>> a 
>>>>> reference from?
>>>>> Thank you.
>>>>>
>>>>> On Wednesday, July 19, 2017 at 2:24:46 AM UTC+3, Xavier Shay wrote:
>>>>>>
>>>>>> Obligatory plug for 
>>>>>> https://www.pluralsight.com/courses/rspec-ruby-application-testing which 
>>>>>> touches on some of the themes you're asking about :)
>>>>>>
>>>>>>
>>>>>> On Tue, Jul 18, 2017, at 04:06 PM, Jon Rowe wrote:
>>>>>>
>>>>>> Hi Jon
>>>>>>
>>>>>> A couple of tips, firstly you can stub out your external dependencies 
>>>>>> for an end to end test, it just depends on the level of integration you 
>>>>>> want, it’s equally fine to do what you propose. For injecting your 
>>>>>> endpoint 
>>>>>> (IP, hostname or otherwise) you have a couple of ways of doing it, the 
>>>>>> simplest is to use environment variables e.g. `ENV[‘API_ENDPOINT’]`, or 
>>>>>> you 
>>>>>> can build yourself a config system like you mention. The reason why you 
>>>>>> don’t see big projects using external configuration files is it is 
>>>>>> usually 
>>>>>> done at the app level rather than in rspec.
>>>>>>
>>>>>> If you chose to go down the config file route, xml, yml or otherwise, 
>>>>>> you’d be better off loading it in a spec_helper or other such support 
>>>>>> file, 
>>>>>> and assigning it somewhere.
>>>>>>
>>>>>> Personally I would go with json fixture files for static json, or a 
>>>>>> generator method if it needs to be dynamic.
>>>>>>
>>>>>> Cheers.
>>>>>> Jon
>>>>>>
>>>>>> Jon Rowe
>>>>>> ---------------------------
>>>>>> [email protected]
>>>>>> jonrowe.co.uk
>>>>>>
>>>>>> On Wednesday, 19 July 2017 at 01:52, Jon Gordon wrote:
>>>>>>
>>>>>>
>>>>>> Hi everyone,
>>>>>>
>>>>>> I'm quite new to RSpec, and I have used it mainly for unit-testing. 
>>>>>> Lately, a need for a small number of end-to-end tests became relevant. 
>>>>>> When 
>>>>>> writing test-cases, I'm trying to stub all dependencies, but because 
>>>>>> that's 
>>>>>> not an option when doing integration tests, I need some help to 
>>>>>> understand 
>>>>>> what's the proper way to do things. Here's couple of questions:
>>>>>>
>>>>>> 1. The test requires an IP for remote machine (which is not local and 
>>>>>> sadly can not be). Obviously, I shouldn't supply the IP inside the spec 
>>>>>> file. The simple way is reading an external YML file with the IP (that 
>>>>>> will 
>>>>>> get created automatically during the CI process with the right IP for 
>>>>>> example) and populate the IP directly from it. But, I was checking 
>>>>>> couple 
>>>>>> of big project that uses rspec, and I never seen an external 
>>>>>> configuration 
>>>>>> file, so I'm thinking perhaps there is a better way of doing it
>>>>>>
>>>>>> 2. If indeed YML file is the right answer, I'm not sure if reading 
>>>>>> from the YML file every spec file (that uses this service) is the right 
>>>>>> thing to do? Shouldn't I be using hooks instead for that?
>>>>>>
>>>>>> 3. The test-object is a REST service, and some of the requests 
>>>>>> require big json object. I have two options: 
>>>>>>     a. I can create the json object in the spec file itself (which 
>>>>>> makes all information visible to you from the spec file itself, but 
>>>>>> clutters the spec)
>>>>>>     b. Creating an external default fixture (which is basically a 
>>>>>> json file), read from it during the spec, and re-write the values that 
>>>>>> are 
>>>>>> relevant for the specific tests.
>>>>>>
>>>>>> Thank you!
>>>>>>
>>>>>>
>>>>>> --
>>>>>> You received this message because you are subscribed to the Google 
>>>>>> Groups "rspec" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>> send an email to [email protected].
>>>>>> To post to this group, send email to [email protected].
>>>>>> To view this discussion on the web visit 
>>>>>> https://groups.google.com/d/msgid/rspec/61ac9ade-1045-4211-80d3-441ef01ae7cb%40googlegroups.com
>>>>>>  
>>>>>> <https://groups.google.com/d/msgid/rspec/61ac9ade-1045-4211-80d3-441ef01ae7cb%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>> .
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> You received this message because you are subscribed to the Google 
>>>>>> Groups "rspec" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>> send an email to [email protected].
>>>>>> To post to this group, send email to [email protected].
>>>>>> To view this discussion on the web visit 
>>>>>> https://groups.google.com/d/msgid/rspec/3FF6FCF2018A482CBDC70C02BAFFB643%40jonrowe.co.uk
>>>>>>  
>>>>>> <https://groups.google.com/d/msgid/rspec/3FF6FCF2018A482CBDC70C02BAFFB643%40jonrowe.co.uk?utm_medium=email&utm_source=footer>
>>>>>> .
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>>
>>>>>> -- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "rspec" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to [email protected].
>>>>> To post to this group, send email to [email protected].
>>>>> To view this discussion on the web visit 
>>>>> https://groups.google.com/d/msgid/rspec/28f3f239-1515-437b-b011-82b2dd163502%40googlegroups.com
>>>>>  
>>>>> <https://groups.google.com/d/msgid/rspec/28f3f239-1515-437b-b011-82b2dd163502%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>>
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>
>>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "rspec" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to [email protected].
>>> To post to this group, send email to [email protected].
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/rspec/c297c4c9-5225-47d9-a6e2-80f461bd1226%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/rspec/c297c4c9-5225-47d9-a6e2-80f461bd1226%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rspec/48d88387-8e71-49a5-b25a-850a79fe4181%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to