Tests do not start automatically

I am trying to set up Guard in my Exercism folder so that all tests run automatically (using guard-minitest).

The folder structure looks like this:

.
β”œβ”€β”€ exercism
└── ruby
    β”œβ”€β”€ bob
    β”‚   β”œβ”€β”€ bob.rb
    β”‚   β”œβ”€β”€ bob_test.rb
    β”œβ”€β”€ etl
    β”‚   β”œβ”€β”€ etl.rb
    β”‚   β”œβ”€β”€ etl_test.rb
...
    └── binary_search_tree
        β”œβ”€β”€ bst.rb
        β”œβ”€β”€ binary_search_tree.rb
        └── README.md

      

Due to the unusual folder structure, I made the following configuration in Guardfile:

# tell Guard to watch all folders under ruby/
all_dirs = Dir.glob('ruby/*')

directories all_dirs

options = {
  test_folders: all_dirs, 
  test_file_patterns: '*_test.rb',
  pride: true
}

guard :minitest, options do   
  watch(%r{^ruby/([^/]+)/([^/]+).rb$})
end

      

With this setup, I expect all my tests to run after any editing of the .rb file.

I start guarding in debug mode.

All tests run on startup as expected.

However, when I edit the .rb file the tests don't run again, although Guard outputs this:

20:43:26 - DEBUG - Interactor was stopped or killed    
20:43:26 - DEBUG - Hook :run_on_additions_begin executed for Guard::Minitest
20:43:26 - DEBUG - Hook :run_on_additions_end executed for Guard::Minitest
20:43:26 - DEBUG - Start interactor

      

I tried many options for security configuration, for example:

watch(%r{^ruby/([^/]+)/([^/]+).rb$}) do |m|
  Dir.glob("ruby/#{m[1]}/*_test.rb").first  
end

      

(I expect this to only run the test from the folder where the file was modified.)

Nothing seems to work. I need to go to guard the interactive console and click ENTERto run the tests.

What am I doing wrong?


EDIT

After reading Cezary's answer below, I have tried a few more things, including trying this in other environments.

Turns out it wasn't a terrible bug, but it was probably the environment I was using.

First, I ran everything in Codio . I moved the project to two other machines, Win8 and Ubuntu 14.04, and it works fine with both Guard File:

all_dirs = Dir.glob('ruby/*')

directories all_dirs

clearing :on

options = {
  test_folders: all_dirs, 
  test_file_patterns: '*_test.rb',
  pride: true
}

guard :minitest, options do
  watch(%r{^ruby/([^/]+)/([^/]+).rb$}) do |m|
    file = Dir.glob("ruby/#{m[1]}/*_test.rb").first
    puts "  Should test #{file}"
    file
  end
end

      

The output guard -d

looks like this:

In the Codio box (where it doesn't work):

<!-- language: lang-none -->

08:55:09 - DEBUG - Interactor was stopped or killed
  Should test ruby/anagram/anagram_test.rb
08:55:09 - DEBUG - Hook :run_on_additions_begin executed for Guard::Minitest
08:55:09 - DEBUG - Hook :run_on_additions_end executed for Guard::Minitest
08:55:09 - DEBUG - Start interactor
[1] guard(main)>

      

On Win / Ubuntu (where it works fine):

<!-- language: lang-none -->

11:02:10 - DEBUG - Interactor was stopped or killed
  Should test ruby/anagram/anagram_test.rb
11:02:10 - DEBUG - Hook :run_on_modifications_begin executed for Guard::Minitest
11:02:10 - INFO - Running: ruby/anagram/anagram_test.rb
Run options: --seed 52507

# Running tests:

..........

Finished tests in 0.001249s, 8006.0205 tests/s, 8006.0205 assertions/s.

10 tests, 10 assertions, 0 failures, 0 errors, 0 skips

11:02:10 - DEBUG - Hook :run_on_modifications_end executed for Guard::Minitest
11:02:10 - DEBUG - Start interactor
[1] guard(main)>

      

I don't know why on Codio I get run_on_additions

, and on the other two I get run_on_modifications

. Anyway, I think the problem is Codio. I've tried with and without manual save and it's the same.

+3


source to share


2 answers


Hi I'm one of the guys "unconditional" for Guard and based on this I wrote a step by step guide: https://github.com/guard/guard/wiki/Understanding-Guard

I highly recommend going through it (rating is appreciated).

Here's a list of things to consider:

  • Structure
  • : If you can, put the tests in a separate top folder, ideally "ruby / test" in your example and the files in "ruby / lib". This is closer to an agreement, and then things like Guard::Minitest

    will work out of the box. (Some editors, such as Vim and Emacs, let you switch between "alternate" files, and they will automatically know where to look for tests or implementation files).

  • Protect registry directories (and that can't even be turned off right now). For small projects, you can just view everything without specifying an option directories

    . But if you have a lot of disk activity in your folder and you have large projects, you will need to choose directories. For example. in your case it will be: directories ruby

    . So `Dir.glob ('ruby / *') doesn't make much sense here.

  • Guard :: Minitest options - If you are using the structure I described, this is optional. If not, I think having test_folder: %w(ruby)

    should be enough. Besides, test_file_patterns

    it is not required as your files seem to follow a standard / conventional agreements ( bob_test.rb

    and etl_test.rb

    ) - if you do not have something really strange, since you have a test within the sets bob.rb

    and etl.rb

    files.

  • Your clock expression doesn't have a block, so it returns files. Unfortunately, when you change the implementation file (for example bob.rb

    ), this file is passed into Guard::Minitest

    , which ignores non-test files (perhaps using the parameter test_file_patterns

    , since it bob.rb

    won't match bob_test.rb

    >, Guard :: Minitest will quietly do ... nothing.

  • Ideally rename Guardfile

    , update your gems (mostly Guard::Minitest

    ) and run bundle exec guard init minitest

    so the "current" recommended template is for Guard::Minitest

    and try to customize it. You will see that by default:

    watch(%r{^lib/(.*/)?([^/]+)\.rb$})  { |m| "test/#{m[1]}test_#{m[2]}.rb" }
    
          

which shows how to translate modified implementation files into test files (which are only files Guard::Minitest

).

In your case, you can:

watch(%r{^ruby/(.*/)?([^/]+)\.rb$}) { |m| "ruby/#{m[1]}/#{m[2]}_test.rb" }

      



I would say regexen is terrible - and I plan to implement glob pattern support, but it will take a while (there are a lot of critical pipeline errors for me).

  1. If that doesn't help - be sure to check the Wiki document above as there are about 20-50 problems you can have with Guard / Listen and most of them are completely outside the control of Guard / Listen. (I would like to change this to make it simpler, so any suggestions would be helpful).

  2. Since bugs are a priority for me, like most maintainers, we rely on the issues reported int GitHub. So we usually don't look at things in Stack Overflow (we expect hard issues to be reported on Github).

Ok I pointed out so many things wrong, time for things you did really, really good:

  • Running Guard

    in debug mode - you are AWESOME for this

  • By showing the output about the changes - you are AWESOME for that too (as it shows that Guard :: Minitest is receiving changes but ignoring them - probably because you are passing implementation files, not test files).

  • Posting such a detailed question is so helpful. Ideally, you shouldn't have experienced a problem (or even had a problem in the first place), but by reporting it, you are showing us what is wrong with Guard on so many levels. (Often, as developers / maintainers, we "get" internals, so we "know" what is wrong right away, even if the docs or messages or debug data don't tell others anything, so problems like this help us a lot to help others).

Thanks again for that - if you ever see other people with problems you can solve, please do so. If you see obvious errors or problems in Guard, please open the problem in Guard. If it's in another plugin repository (for example Guard::Minitest

), just point me out so important issues aren't ignored (mention me as @e2

on GitHub).

I hope to make Guard better - I am currently working hard to make it simpler, more intuitive, more flexible, and more reliable. The more I can count on people to report broken things, the faster I can move forward with cool things.

Thanks again and we have a great day!

+4


source


I had a similar problem where I wanted to use Guard with any new Ruby Exercism exercise I would let go: working on a full suite of tests would work, but tests would not run automatically when files changed. What I did to get this working was the following:

  • Create a general Guardfile

    and place it in ~/exercism/ruby/Guardfile

    with the following content:

    # frozen_string_literal: true
    
    group :red_green_refactor, halt_on_fail: true do
      guard :minitest,
            all_on_start: false,
            test_folders: ["."] do
        # Re-test test files when they're edited.
        watch(%r{\A.+_test\.rb\z}) { |m| "./#{m[1]}" }
        # Run the test file of the (non-test) file that was edited.
        watch(%r{\A(.+)(?<!_test)\.rb\z}) { |m| "./#{m[1]}_test.rb" }
      end
    
      guard :rubocop,
            all_on_start: false,
            cli: ["--display-cop-names"] do
        # Only run Rubocop over implementation files only
        # as test files are not written by me.
        watch(%r{\A(.+)(?<!_test)\.rb\z})
        watch(%r{(?:.+/)?\.rubocop\.yml\z}) { |m| File.dirname(m[0]) }
      end
    end
    
          

  • When starting Guard in the folder with exercises, always specify this Guardfile

    ie guard --guardfile ~/exercism/ruby/Guardfile

    .



Some specific details here about the configuration Guardfile

:

  • The parameter test_folders

    where guard-minitest

    to search for test files is used by default %w[test spec]

    . This is fine for any standard Ruby project, but not for Exercism, where the test file and the implementation file are in the same directory. So it had to be changed to ["."]

    to indicate this.
  • In the blocks for Minitest methods, the watch

    returned string must look like a path, otherwise the tests will simply not run when the file changes (without displaying errors or indicating that something went wrong). For example:

    watch(%r{\A.+_test\.rb\z}) { |m| "#{m[1]}" }

    will not work. It should be watch(%r{\A.+_test\.rb\z}) { |m| "./#{m[1]}" }

    .

0


source







All Articles