É idiomática Ruby para adicionar um método assert () para a classe Kernel do Ruby?

StackOverflow https://stackoverflow.com/questions/147969

  •  02-07-2019
  •  | 
  •  

Pergunta

Eu estou expandindo meu rubi entender por codificação de um equivalente de xUnit de Kent Beck em Ruby. Python (que Kent escreve em) tem um método assert () na língua que é usado extensivamente. Ruby não faz. Eu acho que deveria ser fácil de adicionar isso, mas é Kernel o lugar certo para colocá-lo?

BTW, Eu sei da existência de vários quadros da unidade em Ruby -. Este é um exercício para aprender as expressões Ruby, ao invés de "fazer alguma coisa"

Foi útil?

Solução

Não, não é uma prática recomendada. A melhor analogia para assert () em Ruby é apenas levantando

 raise "This is wrong" unless expr

e você pode implementar suas próprias exceções se você quiser fornecer mais tratamento de exceção específica

Outras dicas

Eu acho que é totalmente válida para usar afirma em Ruby. Mas você está mencionando duas coisas diferentes:

  • estruturas xUnit usar métodos assert para verificar seus testes expectativas. Destinam-se a ser usado em seu código de teste, não no código do aplicativo.
  • Algumas linguagens como C, Java ou Python, incluem uma construção assert destina a ser usado dentro do código de seus programas, para verificar suposições que você faz sobre a sua integridade. Essas verificações são construídos dentro do próprio código. Eles não são um utilitário de tempo de teste, mas um tempo de desenvolvimento um.

Eu escrevi recentemente solid_assert: um pouco biblioteca Ruby implementação de um rubi utilidade afirmação e também um post no meu blog explicando sua motivação .. deixou você escreve expressões no formulário:

assert some_string != "some value"
assert clients.empty?, "Isn't the clients list empty?"

invariant "Lists with different sizes?" do
    one_variable = calculate_some_value
    other_variable = calculate_some_other_value
    one_variable > other_variable
end    

E eles podem ser desactivados de modo assert e invariant obter avaliados como declarações vazias. Isso permitirá que você evitar qualquer problema de desempenho na produção. Mas aviso que Os Pragmatic Programmers recomendo contra desativá-las. Você só deve desativá-los se eles realmente afetar o desempenho.

No que diz respeito à resposta dizendo que a maneira como o Ruby idiomática está usando uma declaração raise normal, eu acho que falta de expressividade. Uma das regras de ouro da programação assertiva não está usando afirmações para o manuseio normal exceção. São duas coisas completamente diferentes. Se você usar a mesma sintaxe para os dois, acho que o código será mais obscura. E, claro, você perde a capacidade de desativá-las.

Você pode estar convencido de que o uso de afirmações é uma coisa boa porque dois must-ler livros clássicos como The Pragmatic Programmer de Journeyman para Mestre e Código completos dedicar toda a seções para eles e recomendar o seu uso. Há também um bom artigo intitulado Programação com afirmações que ilustram muito bem o que é a programação assertiva sobre e quando usá-lo (ele é baseado em Java, mas conceitos se aplicam a qualquer idioma).

Qual é a sua razão para adicionar o método assert para o módulo do kernel? Porque não basta usar outro módulo chamado Assertions ou algo assim?

Como esta:

module Assertions
  def assert(param)
    # do something with param
  end

  # define more assertions here
end

Se você realmente precisa de suas afirmações para estar disponível em todos os lugares fazer algo como isto:

class Object
  include Assertions
end

Disclaimer:. Eu não testar o código, mas, em princípio, eu faria isso como este

Não é especialmente idiomática, mas eu acho que é uma boa idéia. Especialmente se feito assim:

def assert(msg=nil)
    if DEBUG
        raise msg || "Assertion failed!" unless yield
    end
end

Dessa forma, não há nenhum impacto se você decidir não correr com depuração (ou algum outro interruptor conveniente, eu usei Kernel.do_assert no passado) set.

O meu entendimento é que você está escrevendo o seu próprio conjunto de teste como uma maneira de se tornar mais familiarizado com Ruby. Assim, enquanto Test :: Unit pode ser útil como um guia, ele provavelmente não é o que você está procurando (porque já está feito o trabalho).

Dito isso, assert de python é (para mim, pelo menos), mais análoga à de C assert (3) . Não é projetado especificamente para instalações de testes, em vez de casos de captura quando "isso nunca deve acontecer".

Como Ruby embutido testes unitários tendem a ver o problema, então, é que cada classe de caso de teste individual é uma subclasse de TestCase , e que inclui uma "instrução assert", que verifica a validade do que foi passado para ele e registra para relatar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top