Más

¿Cómo invocar un script en la instancia de QGIS que se está ejecutando actualmente desde la línea de comando?

¿Cómo invocar un script en la instancia de QGIS que se está ejecutando actualmente desde la línea de comando?


Desde el símbolo del sistema de Windows (o Batchfile), quiero encontrar la instancia de QGIS en ejecución con un proyecto abierto. Posteriormente, debería iniciarse automáticamente un script (por ejemplo, hacer zoom a algo). Lo he probado conqgis.bat --code

Eso funciona bien, pero siempre inicia una nueva instancia de QGIS. - ¡No quiero eso!

En el futuro, quiero registrar un protocolo de Windows para algo comolink2qgis: layer = "layer" .featid = "123" .action = zoomto

Al hacer clic en esa URL en alguna aplicación de terceros, la instancia de QGIS debe maximizarse y el lienzo del mapa debe ampliarse a la hazaña.

Quizás alguien ya haya hecho algo similar y pueda ayudarme con eso.


Hay dos formas en que veo que puedes hacer esto (puede haber más)

  1. un servidor web que se ejecuta en la instancia de QGIS que escucha solicitudes
  2. enchufes

Para 1. puede usar algo como Flask o el servidor HTTP Python integrado que se ejecuta en un hilo que solo escucha las cosas y actúa sobre ellas. Podría usar algo como Curl (que podría instalarse con QGIS para llamarlo desde la línea de comando)


Ejecutar un trabajo cron de forma manual e inmediata

Tengo un problema específico (el trabajo cron no parece ejecutarse o no se ejecuta correctamente), pero el problema es general: me gustaría depurar los scripts que están cronned. Soy consciente de que puedo configurar una línea crontab * * * * *, pero esa no es una solución completamente satisfactoria. Me gustaría poder ejecutar un trabajo cron desde la línea de comando como si cron lo estuviera ejecutando (mismo usuario, mismas variables de entorno, etc.). ¿Hay alguna forma de hacer esto? No es práctico tener que esperar 60 segundos para probar los cambios en el script.


Si necesita algo más avanzado que una búsqueda exacta del nombre de un comando, ¡no pierda la esperanza! Esto todavía se puede hacer en el lado ps de la tubería. Todo lo que tenemos que hacer es decirle a ps que excluya los procesos grep del resultado:

-C grep selecciona todos los procesos grep y -N niega la selección. Esto se puede usar para buscar argumentos de comando, parte de un nombre de comando o expresiones regulares más complejas.

La forma más sencilla de hacer esto independiente del shell sería almacenarlo en una variable primero:

Llamada: La respuesta grep fnord = (ps aux) de @EmanuelBerg es, con mucho, la más elegante, aunque requiere zsh. Lo tuve brevemente en mis archivos rc, pero bash se queja de esa sintaxis incluso a pesar de un condicional que debería evitar su evaluación.

De mis archivos rc, tengo una versión que no distingue entre mayúsculas y minúsculas que toma los argumentos de grep:

Recorrido por el código, una viñeta por línea de código:

  • Capture la salida ps detallada (en una variable local para que desaparezca cuando la función regrese)
  • Muestre la primera línea (el título) con error estándar para que los resultados se puedan filtrar más sin afectar el título. La sustitución dice: tome $ PS_OUTPUT y elimine todo después de la alimentación de la primera línea (regex equiv: s / n. * $ // msg). Esto evita que hagamos grepping en el título.
  • Muestra la salida ps con todo excepto la primera línea (regex equiv: s /^.* n // m) y grep su contenido con -i para no distingue entre mayúsculas y minúsculas y con todos los argumentos entregados esta función (en el caso de no argumentos, ^, que coincide el comienzo de cualquier línea para que coincida con todo)

Mi respuesta es una variación de la respuesta típica para buscar "foobar" en una lista 'ps'. El argumento de "-A" "ps" es más portátil que "aux", creo, pero este cambio es irrelevante para la respuesta. La respuesta típica se ve así:

En su lugar, uso este patrón:

La principal ventaja es que es más fácil escribir scripts basados ​​en estos patrones porque simplemente concatenas una cadena estática "[^]]" con cualquier patrón que estés buscando. No es necesario quitar la primera letra de la cadena, luego insertarla entre las llaves cuadradas y luego concatenarla nuevamente. Cuando se crea un script en shell, es más fácil simplemente pegar "[^]]" delante del patrón que estaba buscando. Cortar cuerdas en Bash es algo feo, así que mi variación lo evita. Esta variación dice mostrar las líneas donde el patrón coincide SIN un corchete derecho inicial]. Dado que el patrón de búsqueda para excluir un corchete en realidad agrega el corchete al patrón, nunca coincidirá.

Entonces podría escribir un comando 'psgrep' portátil de la siguiente manera. Aquí, hago algunas concesiones para las diferencias entre Linux, OS X BSD y otros. Esto agrega los encabezados de columna de 'ps', proporciona un formato 'ps' más personalizado que se adapta mejor a mis necesidades y muestra la lista de procesos extra, extra ancha para que no se pierda ninguno de los argumentos de la línea de comandos. Bueno, la mayoría no se pierden. Como Java es Java, a menudo hace las cosas de la peor manera posible, por lo que algunos servicios de Java se ejecutarán más allá de la longitud máxima permitida de argumentos que la tabla de procesos realizará un seguimiento. Creo que son 1024 caracteres. La longitud de un solo comando permitida para iniciar un proceso es mucho más larga, pero la tabla de procesos del kernel no se molesta en realizar un seguimiento de cualquier cosa de más de 1K de longitud. Una vez que se inicia el comando, el nombre del comando y la lista de argumentos no son necesarios, por lo que lo que se almacena en la tabla de proceso es solo informativo.


Puede usar el comando de notificación para escribir un archivo de estado.

Crear un script de notificación como:

Y un script get state como:

La lectura del estado actual a través de SNMP ha demostrado ser la más confiable para mí. Para habilitar esto, debe iniciar keepalived con el soporte de snmp:

A continuación, puede consultar el estado de forma fiable mediante

También se puede hacer a través de los scripts de notificación, pero estos no siempre se activan, dejando el archivo de estado desincronizado con la realidad.

en el lado del esclavo puedes ver:

El vaciado del estado actual se puede realizar enviando una señal USR2 a mantener vivo proceso padre:

Vea el resultado en /tmp/keepalived.stats.

Nota: Si SELinux se usaCentOS 7), no permite escribir en este archivo. Puede solucionar esto con esta preparación:

Ahora intente enviar la señal nuevamente.

Con la versión 1.3.0, keepalived agregó una interfaz DBus, que se puede habilitar con la opción enable_dbus en el bloque global_defs del archivo de configuración (sin embargo, la interfaz debe habilitarse con la opción de compilación --enable-dbus durante la configuración, lo que podría no será el caso, si está utilizando un paquete binario).

Puede acceder a la interfaz DBus con cualquier cliente / biblioteca DBus (por ejemplo, dbus-send, gdbus, qdbus). Estoy usando busctl de systemd como ejemplo aquí, porque tiene una interfaz muy agradable:

Hay dos interfaces disponibles, org.keepalived.Vrrp1.Vrrp global en / org / keepalived / Vrrp1 / Vrrp:

Y para cada instancia de VRRP, la interfaz org.keepalived.Vrrp1.Instance en rutas de acuerdo con esta plantilla / org / keepalived / Vrrp1 / Instance / & ltinterface & gt / & ltvirtual-router-id & gt / & ltip-family & gt org.keepalived.Vrrp1.Instance. Para una instancia de IPv4 VRRP con id 1 en eth1 llamada my-instance, obtenemos lo siguiente:

Para obtener el estado de esta instancia en particular, podemos usar el siguiente comando

La propiedad devuelta es un STRUCT, con el código de estado y el nombre legible por humanos. Los estados son 0 "Inicialización", 1 "Copia de seguridad", 2 "Maestro", 3 "Fallo", 4 "Ir a maestro" y 98 "Ir a error". Los últimos tres estados son estados RFC 2338 internos y oficiales.

Si está utilizando varios procesos keepalived y establece la opción de instancia o si está utilizando la función de espacio de nombres de red con la opción de espacio de nombres, el prefijo de ruta cambia / org / keepalived / Vrrp1 / & ltnamespace & gt / & ltinterface & gt.


4 respuestas 4

Para mejorar, use killall y también combine los comandos:

O haz todo en una sola línea:

Enumere los trabajos en segundo plano utilizando

Luego elija el número anterior de trabajo y ejecute

Luego mátelo usando CTRL + C o una forma más fácil de encontrar el PID del script usando

Puede usar ps + grep o pgrep para obtener el proceso nombre/pid luego use killall / pkill para eliminar el nombre del proceso o use kill para eliminar pid. Todos los siguientes deberían funcionar.

Lo más importante es que debes asegurarte de que solo matas el (los) proceso (s) exacto (s) que esperas matar.

pkill / pgrep coincide con un patrón en lugar del nombre exacto, por lo que es más peligroso aquí -x se agrega para que coincida con el nombre exacto.

Además, al usar pgrep / pkill, es posible que necesite

Como probablemente pueda ver, hay muchas formas de hacer esto.

Con respecto a su "ACTUALIZACIÓN # 2", en términos generales, la terminación de cualquier proceso en una jerarquía de padres e hijos generalmente terminará todos los procesos asociados. Pero hay muchas excepciones a esto. Idealmente, desea terminar el 'hijo' final en un árbol de procesos, entonces los padres de este hijo deberían salir si no tienen otras tareas para ejecutar. Pero si mata a un padre, la señal debe transmitirse a los niños cuando el padre muere y los niños también deben salir, pero hay casos en los que los procesos de los niños pueden ignorar la señal (a través de trampas o mecanismos similares) y pueden continuar. ejecutar un será heredado por el proceso 'init' (o similar). Pero este tema del comportamiento del proceso puede volverse complejo y lo dejaré ahí.

Un método que me gusta si no quiero usar un script de control (que se describe a continuación) es usar la utilidad 'pantalla' para iniciar y administrar el proceso. El comando 'pantalla' está lleno de funciones y puede llevar algún tiempo dominarlo. Le animo a que lea la página de manual de 'pantalla' para obtener una explicación completa. Un ejemplo rápido para iniciar un proceso en segundo plano sería el comando:

Esto iniciará "/ ruta / a / programa" dentro de una sesión de 'pantalla'.

Puedes ver tu sesión en ejecución con el comando:

Y en cualquier momento puede volver a conectarse a su programa en ejecución con el comando:

Y luego simplemente termínelo con ^ C o lo que sea.

Además de la belleza de poder reconectarse y desconectarse de su proceso a voluntad, es que 'pantalla' capturará cualquier salida estándar () que su programa pueda producir.

Pero mi preferencia personal en estos asuntos es tener un programa de control que gestione el inicio y la parada de un proceso. Esto puede volverse algo complicado y requiere algunas secuencias de comandos posiblemente complicadas. Y como cualquier guión, hay docenas de buenas formas de hacerlo. He incluido un ejemplo de bash de un método que utilizo habitualmente para iniciar y detener aplicaciones. Si su tarea es simple, puede insertarla directamente en el script de control, o puede hacer que este script de control llame a otro programa externo. Tenga en cuenta que este ejemplo no es completo en términos de gestión del proceso. Dejé de lado la posibilidad de escenarios como: Asegurarme de que el script no se esté ejecutando cuando usa la opción "iniciar", validar que el PID en ejecución es en realidad el proceso que inició (por ejemplo, su script no ha muerto y se inició otro proceso utilizando el mismo PID), y validando que el script realmente respondió (salió) a la primera solicitud 'kill'. Hacer todas estas comprobaciones puede complicarse y no quería que el ejemplo fuera demasiado largo y complejo. Es posible que desee modificar el ejemplo para practicar sus secuencias de comandos de shell.

Guarde el siguiente código en un archivo llamado "programctl", hágalo ejecutable con el comando:

Luego edite el archivo y agregue su código / script en la sección de casos que comienza con "myscript".

Una vez que todo esté en su lugar, asumiendo que "programctl" está en el directorio actual, puede iniciar su programa con:


3 respuestas 3

La siguiente código ejemplo suponga que el Ejecute AppleScript acción comienza con una carrera mando sin ningún lista, p.ej. y consecuentemente termina el script con end run:

Tenga en cuenta que probé esto en macOS Sierra 10.12 y, si bien parece que comienza de nuevo, porque si presiona el botón "Comenzar de nuevo", se repite hasta que selecciona otra opción, no estoy seguro de que esta sea la mejor manera de implementar esto. Digo eso porque no conozco la estructura y codificación del resto del guión y que mayo marcan la diferencia junto con el hecho de que mientras se prueban otros código en cada lado de esto, pude bloquear la aplicación dependiendo de lo que estaba sucediendo si realizaba un bucle más de una vez en este punto.

Entonces, dicho esto, estoy ofreciendo esto como algo para probar a fondo antes de implementarlo en el código final.

Sugeriría simplemente permitir al usuario terminar la aplicación con un mensaje para reiniciar manualmente presionando la combinación de teclas para activar el servicio que inicia la aplicación sobre la implementación de un bucle como este.

Comencé con la solución de user3439894 como mi base, pero tuve que hacer un par de modificaciones para perfeccionar la función de "reinicio" para mi aplicación (como lo recomendaba user3439894).

Al principio, cuando copié directamente la solución, tenía un problema en el que el código se ejecutaba una vez más después de que se completaba la ejecución reiniciada. Pero, por ensayo y error, logré intuir una solución.

Esto es lo que hice para que funcionara:

Pongo la siguiente línea antes de la primera línea del cuerpo principal de mi código:

y al final de mi cuerpo principal de código, pongo:

Según las instrucciones del usuario 3439894, también tuve que eliminar la línea de entrada de retorno predeterminada de esta ubicación (y, de todos modos, no tuve necesidad de devolver la entrada en esta aplicación).

Luego, después de cada diálogo del cual quería que se le presentara al usuario la opción de comenzar de nuevo en ese diálogo, puse:

¡Siguiendo estos pasos, la función "reiniciar" funciona perfectamente! No se repite un número adicional de veces al final, ni tampoco presenta al usuario algún error. También puedo repetir la aplicación varias veces, si así lo deseo, sin errores ni problemas.

Incluso funciona perfectamente cuando los diálogos se encuentran en subrutinas. Tenga en cuenta que mis subrutinas son no dentro del bloque try.

¿Qué sucede cuando necesita utilizar la entrada en su AppleScript?

Me las arreglé para descubrir una solución. Simplemente coloque el código de reinicio dentro de una subrutina:

Por supuesto, la función de reinicio solo lo llevará de regreso al comienzo de esa subrutina, no a la primera línea del cuerpo principal. Pero, si no necesita hacer referencia a la entrada hasta el final de su secuencia de comandos, esto puede funcionar para usted para que pueda tener un botón de reinicio funcional hasta el momento en que necesite la entrada.

Acabo de descubrir una solución aún mejor:

Si envía la entrada a una subrutina, entonces puede tener una función de reinicio mientras tiene acceso a los contenidos de entrada. Ganar-ganar.

Descubrí otro método para reiniciar un AppleScript.

Este método no es "mejor" que los otros métodos que se han proporcionado, es simplemente otra forma de abordar las cosas. Así es como puede reiniciar un archivo .scpt en AppleScript:

Este código simplemente crea otra instancia del archivo .scpt de AppleScript que se está ejecutando actualmente y luego cierra la instancia actual.

Aprendí sobre ejecutar script a partir de un comentario de un usuario. Camelot en la siguiente página web:

Con la misma premisa subyacente, si desea reiniciar un archivo .app usando AppleScript, use esto:

La -n permite que se abra una nueva instancia de la aplicación, incluso si ya se está ejecutando una instancia de esta aplicación. La -n es necesaria porque, en la práctica, la aplicación AppleScript se cierra técnicamente después de que se ha creado la segunda instancia, aunque este no parezca ser el caso según lo que uno ve en su pantalla.

¿Cuándo se debe utilizar este método de reinicio?

Esto se va a volver un poco confuso, así que tengan paciencia.

Tengo un archivo .scpt de AppleScript que se ejecuta automáticamente cuando mi computadora se despierta de la suspensión. (Yo uso SleepWatcher para lograr esto).

Este archivo .scpt llama a una subrutina específica de un archivo .scpt diferente, omite todo el script y solo ejecuta el código que se encuentra en una subrutina específica. (Para lograr esto, utilizo el método descrito aquí).

Este segundo archivo .scpt está plagado de botones "Comenzar de nuevo" en casi todos los diálogos, que emplean:

para lograr el efecto de reinicio. (Este método de reinicio se proporcionó en una respuesta anterior a esta pregunta).

Ahora, el problema es que, mientras mi primer archivo .scpt de hecho se reinicia con éxito el segundo archivo .scpt cuando se regresa al ejecutar se usa en el segundo archivo .scpt, una vez que el script se ha completado, se presenta al usuario un cuadro de diálogo que contiene el siguiente error:

«Script» no entiende el "retorno"

Para ser justos, este error tiene sentido: el primer archivo .scpt no puede comprender completamente el significado de la devolución, porque nunca se ejecutó realmente el otro script. Solo estaba ejecutando una subrutina del otro script.

Este error me molestó. Entonces, jugué un poco más con el código y aprendí sobre ejecutar el script. El tipo específico de escenario que acabo de explicar es donde realmente brilla el método de reinicio del script de ejecución.

El método de ejecución de script simple salva el día: reinicia el segundo archivo .scpt y sin tener que invocar el comando de retorno en el proceso. Por lo tanto, este método está completamente libre de errores, incluso cuando se ejecuta fuera de su código circundante más grande. Este es el único método en esta página que puede hacer esto, ya que los otros métodos dependen de la devolución.


Powershell: ejecute exe en un servidor remoto y capture la salida

Estoy intentando crear un script para la ejecución de un instalador en servidores web remotos. El instalador en cuestión también es un servicio de Windows que aloja NServiceBus. Si se instala RDP en el servidor, la aplicación se instala mediante el siguiente comando:

& amp "$ theInstaller" / install / serviceName: TheServiceName

El instalador imprime la salida sobre su progreso al registrar el servicio y conectarse a la base de datos a stdout, entre otras cosas.

Esto funciona bien desde una sesión RDP, pero cuando lo ejecuto de forma remota a través de PS, obtengo un no puedes-hacer-esto-a-través-de-la-red mensaje si lo ejecuto directamente o mediante Invoke-Command -computername $ theRemoteServer:

System.IO.FileLoadException: No se pudo cargar el archivo o ensamblado 'file: // theRemoteServer c $ thePath AutoMapper.dll' o una de sus dependencias. No se admite la operación. (Excepción de HRESULT: 0x80131515) ---> System.NotSupportedException: Se intentó cargar un ensamblado desde una ubicación de red que habría provocado que el ensamblado estuviera aislado en versiones anteriores de .NET Framework. Esta versión de .NET Framework no habilita la política CAS de forma predeterminada, por lo que esta carga puede ser peligrosa. Si esta carga no está destinada a aislar el ensamblaje, habilite el conmutador loadFromRemoteSources. Consulte http://go.microsoft.com/fwlink/?LinkId=155569 para obtener más información.

(Nota: agregué una "" adicional a la ruta en la primera línea para que se muestre correctamente en la vista previa de este sitio).

Esta y otras DLL son cargadas por el servicio y, aparentemente, el contexto de ejecución del servicio no puede ser remotificado.

También intenté usar Invoke-WmiMethod, que hace alguna cosa, pero no está claro qué, y la salida del instalador se pierde:

Invoke-WMIMethod win32_process create '"$ theInstaller" / install / serviceName: TheServiceName' -ComputerName $ server (con y sin cmd.exe / k antes de la referencia del instalador):

__GENUS: 2
__CLASE: __PARAMETERS
__SUPERCLASS:
__DINASTIA: __PARAMETROS
__RELPATH:
__PROPERTY_COUNT: 2
__DERIVATION: <>
__SERVER:
__NAMESPACE:
__CAMINO :
Identificacion de proceso :
Retorno Valor: 9

¿Cómo se ejecuta de forma remota un EXE de este tipo? y capturar la salida?


Una nota sobre los formatos de archivo¶

Cuando se usa un software externo, abrir un archivo en QGIS no significa que se pueda abrir y procesar también en ese otro software. En la mayoría de los casos, puede leer lo que ha abierto en QGIS, pero en algunos casos, puede que ese no sea el caso. Cuando se utilizan bases de datos o formatos de archivo poco comunes, ya sea para ráster de capas vectoriales, pueden surgir problemas. Si eso sucede, intente utilizar formatos de archivo bien conocidos que esté seguro de que ambos programas comprenden y consulte la salida de la consola (en el cuadro de diálogo de historial y registro) para saber más sobre lo que está fallando.

El uso de capas ráster de GRASS es, por ejemplo, un caso en el que puede tener problemas y no poder completar su trabajo si llama a un algoritmo externo utilizando dicha capa como entrada. Por esta razón, estas capas no aparecerán como disponibles para los algoritmos.

Sin embargo, no debería encontrar ningún problema con las capas vectoriales, ya que QGIS convierte automáticamente del formato de archivo original a uno aceptado por la aplicación externa antes de pasarle la capa. Esto agrega un tiempo de procesamiento adicional, que puede ser significativo si la capa tiene un tamaño grande, por lo que no se sorprenda si se necesita más para procesar una capa desde una conexión de base de datos que una de tamaño similar almacenada en un archivo de forma.

Los proveedores que no utilizan aplicaciones externas pueden procesar cualquier capa que pueda abrir en QGIS, ya que la abren para su análisis a través de QGIS.

En cuanto a los formatos de salida, se pueden utilizar todos los formatos soportados por QGIS como salida, tanto para capas raster como vectoriales. Algunos proveedores no admiten ciertos formatos, pero todos pueden exportar a formatos comunes capas ráster que luego pueden ser transformadas automáticamente por QGIS. Como en el caso de las capas de entrada, si se necesita esta conversión, podría aumentar el tiempo de procesamiento.

Si la extensión del nombre de archivo especificado al llamar a un algoritmo no coincide con la extensión de ninguno de los formatos admitidos por QGIS, se agregará un sufijo para establecer un formato predeterminado. En el caso de capas ráster, el tif se utiliza la extensión, mientras que shp se utiliza para la capa vectorial.


Para obtener información sobre el mantenimiento y la compatibilidad con las versiones principales del SDK y sus dependencias subyacentes, consulte lo siguiente en la Guía de referencia de herramientas y SDK de AWS:

Amazon Web Services (AWS) es una colección de servicios de infraestructura digital que los desarrolladores pueden aprovechar al desarrollar sus aplicaciones. Los servicios incluyen computación, almacenamiento, base de datos y sincronización de aplicaciones (mensajería y cola). AWS utiliza un modelo de servicio de pago por uso. Solo se le cobrará por los servicios que usted o sus aplicaciones utilicen. Además, para hacer que AWS sea más accesible como plataforma para la creación de prototipos y la experimentación, AWS ofrece un nivel de uso gratuito. En este nivel, los servicios son gratuitos por debajo de cierto nivel de uso. Para obtener más información sobre los costos de AWS y la capa gratuita, consulte Prueba de conducción de AWS en la capa de uso gratuito. Para obtener una cuenta de AWS, abra la página de inicio de AWS y luego haga clic en Inscribirse.

¡Gracias por informarnos que estamos haciendo un buen trabajo!

Si tiene un momento, díganos qué hicimos bien para que podamos hacer más.

Gracias por informarnos que esta página necesita ser mejorada. Lamentamos haberte defraudado.

Si tiene un momento, díganos cómo podemos mejorar la documentación.


Scripter mssql

Mssql-scripter es la línea de comandos multiplataforma equivalente a la experiencia del Asistente para generar secuencias de comandos ampliamente utilizada en SSMS.

Puede usar mssql-scripter en Linux, macOS y Windows para generar scripts T-SQL de lenguaje de definición de datos (DDL) y lenguaje de manipulación de datos (DML) para objetos de base de datos en SQL Server que se ejecutan en cualquier lugar, Azure SQL Database y Azure SQL Data Warehouse . Puede guardar el script T-SQL generado en un archivo .sql o canalizarlo a las utilidades estándar * nix (por ejemplo, sed, awk, grep) para más transformaciones. Puede editar el script generado o registrarlo en el control de código fuente y, posteriormente, ejecutar el script en sus procesos de implementación de bases de datos SQL existentes y canalizaciones DevOps con herramientas de línea de comandos SQL multiplataforma estándar como sqlcmd.

Mssql-scripter se crea con Python e incorpora los principios de usabilidad de las nuevas herramientas de la CLI 2.0 de Azure. El código fuente se puede encontrar en Github en https://github.com/Microsoft/sql-xplat-cli, ¡y agradecemos sus contribuciones y solicitudes de extracción!

Genere scripts DDL para todos los objetos de la base de datos (predeterminado) en la base de datos Adventureworks y envíelos a stdout

Genere scripts DDL para todos los objetos de la base de datos y scripts DML (instrucciones INSERT) para todas las tablas en la base de datos Adventureworks y guarde el script en un archivo


Ver el vídeo: Automatización de Pruebas con Selenium WebDriver + Java. Tutorial paso a paso