Sono d'accordo con Rainer Joswig's answer; in generale, questo è un compito molto difficile da risolvere perché i macro possono fare molto. Tuttavia, vorrei sottolineare che in molti casi, il metodo più semplice per testare le macro è fare in modo che le macro facciano il meno possibile. In molti casi, l'implementazione più semplice di una macro è semplicemente lo zucchero sintattico attorno a una funzione più semplice. Ad esempio, c'è un tipico schema di with- & hellip; macro in Common Lisp (ad esempio, con-open-file di), in cui la macro incapsula semplicemente un po 'di codice standard:
(defun make-frob (frob-args)
;; do something and return the resulting frob
(list 'frob frob-args))
(defun cleanup-frob (frob)
(declare (ignore frob))
;; release the resources associated with the frob
)
(defun call-with-frob (frob-args function)
(let ((frob (apply 'make-frob frob-args)))
(unwind-protect (funcall function frob)
(cleanup-frob frob))))
(defmacro with-frob ((var &rest frob-args) &body body)
`(call-with-frob
(list ,@frob-args)
(lambda (,var)
,@body)))
Le prime due funzioni qui, make-frob e pulizia-frob sono relativamente semplici per il test unitario. call-with-frob è un po 'più difficile. L'idea è che si supponga di gestire il codice boilerplate della creazione del frob e assicurare che la chiamata di cleanup avvenga. È un po 'più difficile da controllare, ma se il boilerplate dipende solo da alcune interfacce ben definite, allora probabilmente sarai in grado di creare un finto frob in grado di rilevare se è stato ripulito correttamente. Infine, la macro with-frob è così semplice che è possibile testarla come avevate pensato, ovvero verificarne l'espansione. O potresti dire che è abbastanza semplice che non hai bisogno di testarlo.
D'altra parte, se si sta guardando una macro molto più complessa, come ad esempio ciclo, che è in realtà una sorta di compilatore a sé stante, il gioco è quasi certamente già andando ad avere l'espansione logica in alcune funzioni separate. Ad esempio, si potrebbe avere
(defmacro loop (&body body)
(compile-loop body))
nel qual caso davvero non hanno bisogno di testare ciclo, è necessario testare compilazione ciclo, e poi sei di nuovo nel regno della vostra unità al solito test.
fonte
2016-01-03 00:57:25
ho iniziato ad esaminare l'effetto fine del m acro, non l'espansione intermedia. Grande domanda però, non vedo l'ora di ricevere le risposte. –